Django multiple forms one Submit

2019-07-23 06:11发布

问题:

I know this question has been answered before on this site, but for the life of me I can't figure it out. I want to submit two forms at once, with one submit button. Please, can anybody identify what is wrong with my code, this is driving me insane.

HTML template (edited)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head>

<body>



<form action="{% url "list" %}" method="post" enctype="multipart/form-data">

                {% csrf_token %}
                <p>{{ form.non_field_errors }}</p>

                <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>

                <p>
                    {{ form.docfile.errors }}
                    {{ form.docfile }}
                </p>


                <p>{{ form.non_field_errors }}</p>

                <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>

                <p>
                    {{ form.docfile.errors }}
                    {{ form.docfile }}
                </p>

                <p><input type="submit" value="Upload"/></p>
            </form>   

            <!-- check error
            {% if form.errors %}
            {% for field in form %}
            {% for error in field.errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
            {% endfor %}
            {% endfor %}
            {% for error in form.non_field_errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
            {% endfor %}
            {% endif %} -->

        </body>

views.py

# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
from myproject.myapp.forms import DocumentForm2


def list(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, prefix="form")
        form2 = DocumentForm2(request.POST, prefix="form2")

        if form.is_valid() or form2.is_valid(): 
            newdoc = Document(docfile=request.FILES['docfile'])
            newdoc.save()

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myproject.myapp.views.list'))
    else:
        form = DocumentForm(prefix="form")  # A empty, unbound form
        form2 = DocumentForm2(prefix="form2")  # A empty, unbound form

    # Load documents for the list page
    documents = Document.objects.all()

    # Render list page with the documents and the form
    return render_to_response(
        'list.html',
        {'documents': documents, 'form': form},
        context_instance=RequestContext(request)
    )

forms.py

# -*- coding: utf-8 -*-

from django import forms


class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file'
        )

class DocumentForm2(forms.Form):
    docfile2 = forms.FileField(
        label='Select a file'
        )

回答1:

First, you have 2 forms defined in your views method form and form2, but you only add form to your context.

Secondly, you don't put 2 forms in two different <form> tags. You should put them in one so you could submit them at the same time.

Thirdly, not related, but you CANNOT name your views method list. That's a django keyword for data structure list, you could run into huge trouble if you try to use list in other functions in your views file.

Edit:

You keep using variable {{ form.something }} but you have 2 forms, so you just render the first form twice but completely ignored the second form. You should:

<form action="{% url "list" %}" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    {{ form2.as_p }}
    <p><input type="submit" value="Upload"/></p>
</form>

ReEdit:

I'm not sure what caused the 403 to happen, but let's try replace render_to_response with render:

from django.shortcuts import render

def list(request):
    # your code here
    return render(request, 'list.html', {'documents': documents, 'form': form, 'form2': form2})