Как создать несколько форм на одной странице в Django? - PullRequest
0 голосов
/ 15 апреля 2019

Я хочу иметь 2 разные формы на моей странице. Но когда я пытаюсь сохранить значение форм, они сохраняются только в form_fridge. Я думаю, это существует, потому что я использую один csrf_token для 2 форм. Вы можете мне помочь?

    <form method="POST" enctype="multipart/form-data" id = "formTv">
    {% csrf_token %}
    {{ form_tv.as_p }}
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

    <form method="POST" enctype="multipart/form-data" id = "formFridge">
    {% csrf_token %}
    {{ form_fridge.as_p }}
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

views.py

def add_new(request):
    form_fridge = FridgeForm(request.POST, request.FILES, use_required_attribute=False)
    form_tv = TvForm(request.POST, request.FILES, use_required_attribute=False)
    if form_fridge.is_valid() and request.method == 'POST':
        form_fridge.save()
        return redirect('new')
    elif form_tv.is_valid() and request.method == 'POST':
        form_tv.save()
        return redirect('new')
    return render(request, 'appliances/add_new.html', {'form_tv': form_tv,
                                                       'form_fridge': form_fridge})

Ответы [ 3 ]

0 голосов
/ 15 апреля 2019

Проблема в том, что у вас есть два отдельных элемента HTML <form> и кнопки отправки. Если вы хотите, чтобы обе формы отправлялись и обрабатывались одновременно, они должны находиться в одном и том же элементе формы.

<form method="POST" enctype="multipart/form-data" id = "formTv">
{% csrf_token %}
{{ form_tv.as_p }}

{{ form_fridge.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>

Возможно, вы также захотите использовать аргумент prefix при создании экземпляров ваших форм в представлении, чтобы избежать столкновения полей с одинаковыми именами.

0 голосов
/ 15 апреля 2019

Вы должны добавить скрытое поле, чтобы отличить, какая форма была отправлена.

<form method="POST" enctype="multipart/form-data" id = "formTv">
    {% csrf_token %}
    {{ form_tv.as_p }}
    <input type="hidden" id="form_type" name="form_type" value="form_tv">
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

    <form method="POST" enctype="multipart/form-data" id = "formFridge">
    {% csrf_token %}
    {{ form_fridge.as_p }}
    <input type="hidden" id="form_type" name="form_type" value="form_fridge">
    <button type="submit" class="save btn btn-default">Save</button>
    </form>

Таким образом, когда одна из форм отправлена, вы можете найти, какая форма была отправлена.

#views.py
def add_new(request):
    if request.method == "POST":  #check if the request is POST call or not.
        form_type = request.POST.get("form_type")
        form = None
        # check which form to evaluate
        if form_type == "form_fridge":
            form = FridgeForm(request.POST, request.FILES, use_required_attribute=False)

        if form_type == "form_tv":
            form = TvForm(request.POST, request.FILES, use_required_attribute=False)

        # evaluate the form
        if form and form.is_valid():
            form.save()
            return redirect('new')

    return render(request, 'appliances/add_new.html', {'form_tv': form_tv,
                                                       'form_fridge': form_fridge})
0 голосов
/ 15 апреля 2019

Допустим, вам нужно выполнить две формы:

class ContactForm(forms.Form):
    title = forms.CharField(max_length=150)
    message = forms.CharField(max_length=200, widget=forms.TextInput)


class SubscriptionForm(forms.Form):
    email = forms.EmailField()

Django FormView - это основной класс для обработки форм таким способом.Как минимум, ему необходимо:

Атрибут form_class, указывающий на класс, форму которого мы хотим обработать.

Атрибут success_url, чтобы указать, какой URL перенаправлять при успешной обработке формы.

Метод form_valid для выполнения фактической логики обработки.

Итак, в ваших представлениях:

class MultipleFormsDemoView(MultiFormsView):
    template_name = "pages/cbv_multiple_forms.html"
    form_classes = {'contact': ContactForm,
                    'subscription': SubscriptionForm,
                    }

    success_urls = {
        'contact': reverse_lazy('contact-form-redirect'),
        'subscription': reverse_lazy('submission-form-redirect'),
    }

    def contact_form_valid(self, form):
        'contact form processing goes in here'

    def subscription_form_valid(self, form):
        'subscription form processing goes in here'

В вашем шаблоне:

<form method="post">{% csrf_token %}
    {{ forms.subscription }}
    <input type="submit" value="Subscribe">
</form>
<form method="post">{% csrf_token %}
    {{ forms.contact }}
    <input type="submit" value="Send">
</form>

Вы также можете проверить встроенные формы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...