Использование нескольких форм на странице в Django

Как мне использовать более одной формы на странице в Django?


person rajkumar    schedule 02.05.2011    source источник
comment
Пожалуйста, предоставьте дополнительную информацию, иначе мы не сможем вам помочь.   -  person Felix Kling    schedule 02.05.2011
comment
возможный дубликат Правильный способ обработки нескольких форм на одна страница в Django   -  person Anto    schedule 17.07.2013


Ответы (2)


Ознакомьтесь со следующими ранее заданными (и отвеченными) вопросами:

Django: несколько моделей в одном шаблоне с использованием форм

и

Правильный способ обработки нескольких форм на одной странице в Django.

В зависимости от того, о чем вы действительно спрашиваете, это мой любимый способ работы с разными моделями на одной странице:

if request.POST():
    a_valid = formA.is_valid()
    b_valid = formB.is_valid()
    c_valid = formC.is_valid()
    # we do this since 'and' short circuits and we want to check to whole page for form errors
    if a_valid and b_valid and c_valid:
        a = formA.save()
        b = formB.save(commit=False)
        c = formC.save(commit=False)
        b.foreignkeytoA = a
        b.save()
        c.foreignkeytoB = b
        c.save()
person Herman Schaaf    schedule 04.05.2011
comment
спасибо за ваше объяснение. В моем случае у меня есть две модели (родительская и дочерняя), и обе формы отображаются в одном шаблоне. Когда я отправляю форму, parent.is_valid () возвращает true, но child.is_valid () имеет значение false, а ошибка говорит, что это поле не может быть пустым, если это поле является моим полем модели внешнего ключа в дочерней модели - person Shahriar Rahman Zahin; 28.05.2020

Судя по дате ваших вопросов, я предполагаю, что вы используете представления на основе классов, ниже скопировано из моего другого ответа здесь: Правильный способ обработки нескольких форм на одной странице в Django

class NegotiationGroupMultifacetedView(TemplateView):
    ### TemplateResponseMixin
    template_name = 'offers/offer_detail.html'

    ### ContextMixin 
    def get_context_data(self, **kwargs):
        """ Adds extra content to our template """
        context = super(NegotiationGroupDetailView, self).get_context_data(**kwargs)

        ...

        context['negotiation_bid_form'] = NegotiationBidForm(
            prefix='NegotiationBidForm', 
            ...
            # Multiple 'submit' button paths should be handled in form's .save()/clean()
            data = self.request.POST if bool(set(['NegotiationBidForm-submit-counter-bid',
                                              'NegotiationBidForm-submit-approve-bid',
                                              'NegotiationBidForm-submit-decline-further-bids']).intersection(
                                                    self.request.POST)) else None,
            )
        context['offer_attachment_form'] = NegotiationAttachmentForm(
            prefix='NegotiationAttachment', 
            ...
            data = self.request.POST if 'NegotiationAttachment-submit' in self.request.POST else None,
            files = self.request.FILES if 'NegotiationAttachment-submit' in self.request.POST else None
            )
        context['offer_contact_form'] = NegotiationContactForm()
        return context

    ### NegotiationGroupDetailView 
    def post(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)

        if context['negotiation_bid_form'].is_valid():
            instance = context['negotiation_bid_form'].save()
            messages.success(request, 'Your offer bid #{0} has been submitted.'.format(instance.pk))
        elif context['offer_attachment_form'].is_valid():
            instance = context['offer_attachment_form'].save()
            messages.success(request, 'Your offer attachment #{0} has been submitted.'.format(instance.pk))
                # advise of any errors

        else 
            messages.error('Error(s) encountered during form processing, please review below and re-submit')

        return self.render_to_response(context)

Шаблон html имеет следующий эффект:

...

<form id='offer_negotiation_form' class="content-form" action='./' enctype="multipart/form-data" method="post" accept-charset="utf-8">
    {% csrf_token %}
    {{ negotiation_bid_form.as_p }}
    ...
    <input type="submit" name="{{ negotiation_bid_form.prefix }}-submit-counter-bid" 
    title="Submit a counter bid"
    value="Counter Bid" />
</form>

...

<form id='offer-attachment-form' class="content-form" action='./' enctype="multipart/form-data" method="post" accept-charset="utf-8">
    {% csrf_token %}
    {{ offer_attachment_form.as_p }}

    <input name="{{ offer_attachment_form.prefix }}-submit" type="submit" value="Submit" />
</form>

...
person Daniel Sokolowski    schedule 25.06.2013
comment
Это: _1 _ !!!! - person zeraien; 27.03.2015
comment
@zeraien? - можете уточнить - person Daniel Sokolowski; 27.03.2015
comment
При наличии нескольких форм на одной странице добавление ключа / значения к кнопке отправки было тем, что позволило мне различать разные формы в коде обработки представления. Итак, в моем случае я создал небольшой метод, который я вызываю для каждой формы ... def _get_post(request, prefix): return request.POST if '%s-submit' % prefix in request.POST else None, и каждая форма просто вызывает его для получения данных POST: password_form = PasswordChangeForm(user=request.user, data=_get_post(request, 'password'), prefix='password') Эта строка вдохновила меня на это ;-) - person zeraien; 29.03.2015