Search code examples
pythondjangodjango-formsdjango-tables2

Using django-tables2 form to send selection to another form - nothing saves?


I have a django-tables2 form that passes selected model items to a second form. The goal of the second form is to allow a user to edit values that will be applied to all the items. My problem is that the second form fails validation and then the input values don't get saved. How can I link these two forms and allow user input before the form tries to validate? It seems like the POST request goes from the table through the second form -- is there a way to interrupt it or start a second request?

image_list.html:

<form method="post" action="{% url 'ExifReader:delete_image_list' %}">
  {% render_table table %}
  {% csrf_token %}
  <button type="submit" style="margin-right:10px" class="btn btn-primary" name="edit_FAN">Edit Exif</button>
  <button type="submit" style="margin-right:10px" class="btn btn-danger" onclick="return confirm('Delete?')" name="delete_images">Delete Images</button>
</form>

Note: The delete_images button works fine.

views.py:

def delete_image_list(request):
    if request.method == 'POST':
        if 'delete_images' in request.POST:
            pks = request.POST.getlist('selection')
            # Delete items...

        elif 'edit_FAN' in request.POST:
            form = EditFANForm()
            pks = request.POST.getlist('selection')
            imgs = []
            for pk in pks:
                ex = exif.objects.get(pk=pk)
                imgs.append(ex.image_id)
            if request.method == 'POST':
                print('POST')
                for img in imgs:
                    print(image.objects.get(pk=img))
                    form = EditFANForm(instance=image.objects.get(pk=img))
                    if form.is_valid():
                        print('Valid')
                        formS = form.save(commit=False)
                        img.FAN = formS.FAN
                        fromS.save()
                    else:
                        print('ERRORS: ', form.errors)
            return render(request, 'ExifReader/edit_fan_form.html', {'form': form, 'pks':pks})

When I click the button for "edit_FAN" from the table view, the EditFANForm renders correctly, I can enter values, get redirected back to the table view, but none of the values are saved. From the print commands I added for tracing the code, I get the following in console:

POST
774
ERRORS:   <bound method BaseForm.non_field_errors of <EditFANForm bound=False, valid=False, fields=(FAN;collection;tags)>>

Where "774" is the selected object.
So it looks to me like the form gets to the part where values can be edited (EditFANForm), but the form POSTs before the user can input values, hence the form doesn't validate (but there also aren't any errors?).

Where am I going wrong? How can I save the values from the second form?

Python 3.6.8, Django 2.2.6


Solution

  • I figured out a solution that seems to work fine: add a redirect to another view to process the second form. Messages from django.contrib are used to pass context data to the second view and form (in this case the selected objects from the table).

    from django.contrib import messages
    
    def delete_image_list(request):
        ...
        elif 'edit_FAN' in request.POST:
            pks = request.POST.getlist('selection')
            messages.add_message(request, messages.INFO, pks)
            return HttpResonseRedirect(reverse('ExifReader:images_list_edit'))
    
    def images_list_edit(request):
        if request.method == 'POST':
        ...