简体   繁体   English

在提交无效表单后运行Django ModelForm __init __()方法中的所有代码

[英]Run all the code in a Django ModelForm __init__() method after an invalid form submission

Based on this model: 基于这个模型:

class Booking(models.Model):
    """
    Model Booking with foreign key to models Session and Bundle.
    """
    session = models.ForeignKey(verbose_name=_('Session'), to=Session, default=None, null=False, blank=False)
    bundle = models.ForeignKey(verbose_name=_('Bundle'), to=Bundle, default=None, null=True, blank=True)
    price = models.DecimalField(verbose_name=_('Price'), max_digits=10, decimal_places=2,
                                default=None, null=False, blank=False)
    name = models.CharField(verbose_name=_('Name'), max_length=100, default=None, null=False, blank=False)
    email = models.EmailField(verbose_name=_('Email'), null=True, blank=True)
    phone_number = models.CharField(verbose_name=_('Phone Number'), max_length=30, null=True, blank=True)

    def __str__(self):
        return "%s @%s" % (self.name, self.bundle if self.bundle else self.session)

I have the following ModelForm : 我有以下ModelForm

class BookingForm(forms.ModelForm):
    name = forms.CharField(max_length=100, required=True)

    class Meta:
        model = Booking
        fields = ['session','bundle', 'name', 'email', 'phone_number']
        widgets = {
            'bundle': forms.RadioSelect,
            'session': forms.HiddenInput,
        }

    def __init__(self, *args, **kwargs):
        session_pk = kwargs.pop('session', False)
        super(BookingForm, self).__init__(*args, **kwargs)

        if session_pk is not False:
            session = Session.objects.filter(pk=session_pk).first()
            if session:
                self.fields['session'].initial = session
            if not session or not session.is_bookable:
                raise Exception("Session is not available")
            elif session.bundles:
                self.fields['bundle'].widget.attrs['choices'] = session.bundles
                self.fields['bundle'].initial = session.bundles[0] if len(session.bundles) == 1 else None
                self.fields['bundle'].empty_label = None
            else:
                del self.fields['bundle']

Using this Class-based CreateView : 使用这个基于类的CreateView

class BookingCreateView(generic.CreateView):
    template_name = 'events/booking_form.html'
    form_class = BookingForm

     def get_form_kwargs(self):
        """
        Extended method so we can pass in the Session object's pk. 
        """
        kwargs = super(BookingCreateView, self).get_form_kwargs()

        if self.request.method == 'GET':
            session_kwarg = {
                'session': self.kwargs.get('pk', None),
            }
            kwargs.update(session_kwarg)
        return kwargs

I only want the bundle field to be displayed if the session field has associated bundles, as the code shows. 如果会话字段具有关联的包,我只希望显示包字段,如代码所示。 It works when I first render the template. 它在我第一次渲染模板时有效。 However if I post the form with invalid fields, the bundle field will be rendered along with the other fields. 但是,如果我使用无效字段发布表单,则字段将与其他字段一起呈现。

Question: How can I make the logic inside my init () be executed after the form has been submitted incorrectly? 问题:如何在表单提交错误后执行init ()中的逻辑? Preferentially without having to recur to JavaScript. 优先,无需重复使用JavaScript。

So I've figured out how to solve my problem: 所以我想出了如何解决我的问题:

In my ModelForm I changed the signature of the __init__ method to pass in my session value outside of the kwargs: 在我的ModelForm我更改了__init__方法的签名,以便在kwargs之外传递我的session值:

def __init__(self, session=None, *args, **kwargs):
    session_pk = session
    super(BookingForm, self).__init__(*args, **kwargs)

And then, in my CreateView method get_form_kwargs(self) , I was checking the condition: 然后,在我的CreateView方法get_form_kwargs(self) ,我正在检查条件:

if self.request.method == 'GET'

It happened that I wasn't passing any session in the form's kwargs when request.method == 'POST' . 碰巧的是,当request.method == 'POST'时,我没有在表单的kwargs中传递任何session Problem solved! 问题解决了!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM