Jim Jim - 14 days ago 5
HTML Question

Get Table selection and File in same form POST

I have a django template that houses a django_table2 table, and also accepts a file:

{% extends 'portal/base.html' %}
{% load render_table from django_tables2 %}
{% block title %}{{user.first_name }} {{ user.last_name }} Portal{% endblock %}

{% block content %}

<input type=button value="Back" onClick="javascript:history.go(-1);">
<h4>Currently registered vehicles:</h4>
<div class='vehlist'>
<form action="/loadlocndb/" method="POST">
{% csrf_token %}
{% render_table veh_list %}


<h4> Location database .csv file</h4>
<input type="file" name="myfile"><br/>
<input type="submit" value="Submit" />
</form>
</div>
{% endblock %}


Currently the only thing passed back in
POST
is the selected table checkboxes. How do I also pass back the file as well.

views.py

@login_required
def locndb(request):
# This is the basic user landing Page
veh_list =VehicleTable(Vehicle.objects.filter(company__user=request.user))
form = LocnDBForm()
RequestConfig(request).configure(veh_list)
return render(request, 'portal/locndb.html', {"veh_list": veh_list, "form": form})

@login_required
def loadlocndb(request):


if request.method == "POST":
pks = request.POST.getlist("update")
print pks
selected_objects = Vehicle.objects.filter(pk__in=pks)

vlist = []
for i in selected_objects:
vlist.append(i)

return render(request, 'portal/loadlocndb.html',{"vlist":vlist})


forms.py

from django import forms
from django.contrib.auth.models import User
from portal.models import UserProfile, Vehicle

class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())

class Meta:
model = User
fields = ('username', 'email', 'password')

class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('milkco', 'compName')

class LocnDBForm(forms.ModelForm):
class Meta:
model = Vehicle
fields = ('vehid','locndb',)


vehicle model

class Vehicle(models.Model):
vehid = models.CharField(max_length = 10)
company = models.ForeignKey(UserProfile, default = 1)
#depot = models.ForeignKey(Depot, default = 1)
locndb = models.FileField(upload_to="optiload/", default= "setting.MEDIA_ROOT/locndb/LocnDB.csv")

class Meta:
db_table = "vehicle"

def __unicode__(self):
return self.vehid


Even better is how would stop the user from processing without selecting at least one entry in the table and also a file.

Thanks

Answer

I updated your loadlocndb view:

@login_required   
def loadlocndb(request):


if request.method == "POST":
    pks = request.POST.getlist("update")

    myfile = request.FILES['form_field_name'].file
    print pks, myfile

    selected_objects = Vehicle.objects.filter(pk__in=pks)

    vlist = []
    for i in selected_objects:
        vlist.append(i)

    return render(request, 'portal/loadlocndb.html',{"vlist":vlist})

I haven't tested it, but this: request.FILES['form_field_name'].file will get the file from your form. Just replace your file form field name with 'form_field_name'.

Can you please put your code from your form.py?

And in your template, you should replace <form action="/loadlocndb/" method="POST"> with <form action="/loadlocndb/" method="POST" enctype="multipart/form-data">.

From documentation: Note that request.FILES will only contain data if the request method was POST and the <form> that posted the request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.

Comments