Larry Martell
Larry Martell

Reputation: 3756

Having trouble posting a form in django and getting all the arguments

I have a form in django:

class UploadForm(forms.Form):
    klarf_files = forms.FileField(label='Select a file')
    pixel_size = forms.CharField()
    fov = forms.CharField()
    template_recipe = forms.CharField()
    template_target = forms.CharField()

When I post the form I only get the klarf_files fields and not any of the others. The The form does not have the cleaned_data dictionary as the docs say it should, but I can get the files by doing this:

form = UploadForm(request.POST, request.FILES)
files = request.FILES.getlist('klarf_files')

But I need the others as well. After screwing around with this for over a day I decided to just brute force it and add the parameters to the form's action attribute, e.g.:

$('#upload').attr('action', "?pixel_size="+$('#pixel_size').val());

This works, but this created a different issue: I want the form to go to a certain view. In my original form I had this:

<form id="upload" method="POST" enctype="multipart/form-data"
  action="/report/CDSEM/DR4iBeta/dr4iupload/">

I added a onsubmit function so I could add my parameters to the action attribute, but that seems to make it ignore the form action. I found that it was not going the the above view, but instead to /report/CDSEM/DR4iBeta/. So then I tried to redirect it in then onsubmit function, but that turned it into a GET and I lost the files.

I'd like to know why I'm not getting form's cleaned_data dictionary as I should, or I'd like to know how I can add the parameters and still have it be a POST and go to where I need it to.

Here is my template:

  <form id="upload" method="POST" enctype="multipart/form-data"
  action="{% url motor.core.reports.views.upload the_controller.app.name the_controller.get_name %}">
  {% csrf_token %}
  <label for="id_pixel_size">Pixel Size</label><br />
  <input type="text" value="{{ pixel_size_default }}" id="id_pixel_size" name="pixel_size">
  <label for="id_fov">FOV</label><br />
  <input value="{{ fov_default }}" id="id_fov" name="fov">
  <label for="id_template_recipe">Template Recipe</label><br />
  <input value="{{ template_recipe_default }}" id="id_template_recipe" name="template_recipe">
  <label for="id_template_target">Template Target</label><br />
  <input value="{{ template_target_default }}" id="id_template_target" name="template_target">
  <input type="file" name="klarf_files" id="klarf_files" multiple=""/>
  <input type="submit" class="submit" value="Upload"/>
  </form>

Upvotes: 0

Views: 64

Answers (1)

Peter DeGlopper
Peter DeGlopper

Reputation: 37319

The form will not have cleaned_data until the form has been validated. The traditional way to do this is to check is_valid in the view that accepts the form:

if form.is_valid():
    klarf_file = form.cleaned_data['klarf_files']
    # and further processing as needed
else:
    # traditionally you rerender the form display template here to show errors

I think that's the core of your problem - attempts to work around it by manually inserting parameters in the action should not be necessary at all.

Upvotes: 2

Related Questions