[英]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.