以父表单中的字段值为条件验证内联表单集
Validation of an inline formset conditional to the value of a field from the parent form
我想在 django 内联表单集 (form_date_event
) 中使用自定义验证,以便根据父 (form_event
) 表单上的一个值获得不同的验证。
具体来说,如果 form_event
的类型是 'recording release',我希望 form_date_event
内联格式集能够接受空位置。我怎样才能做到这一点?下面的 type = cleaned_data.get('type')
不起作用,我想是因为它获取的是表单集的 clean data
,而不是父表单的
models.py
:
class Venue(models.Model):
venue_name = models.CharField(max_length=50)
class Event(models.Model):
EV_TYPE = (
('performance', 'performance'),
('recording release', 'recording release'),
('other', 'other'),
)
title = models.CharField(max_length=200)
type = models.CharField(max_length=20, choices=EV_TYPE, default="performance")
class dateEvent(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
start_date_time = models.DateTimeField(auto_now=False, auto_now_add=False)
forms.py
:
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = [
'type',
'title',
]
views.py
:
class BaseDateEventFormSet(BaseInlineFormSet):
def clean(self):
cleaned_data = super().clean()
type = cleaned_data.get('type')
if type == 'recording release':
self.add_error('repertoire', _("This field is required"))
return cleaned_data
def event_edit_view(request, id):
event = get_object_or_404(Event, id=id)
active_user = request.user
form_event = EventForm(request.POST or None, instance=event)
DateEventFormSet = inlineformset_factory(Event, dateEvent, extra=5, can_delete=True, fields=('event', 'start_date_time', 'venue', 'link', 'link_description'),
form_date_event = DateEventFormSet(request.POST or None, instance=Event.objects.get(id=id), prefix="dateEvent", queryset=dateEvent.objects.filter(event__id=id))
context = {
'event': event,
'id': event.id,
'form_event': form_event,
'form_date_event': form_date_event,
}
if request.method == "POST":
if form_event.is_valid() and request.POST['action'] == 'submit':
if form_date_event.is_valid():
flag=False
evt_type = form_event.cleaned_data.get('type')
for form in form_date_event:
print(form.cleaned_data.get('venue'))
if form.cleaned_data.get('venue') is None and evt_type !="recording release":
flag = True
break
if flag:
messages.error(request,'Venue can be blank only for recording release events')
return render(request, "events/event-edit.html", context)
else:
form_event.save()
form_date_event.save()
return redirect('my-events')
else:
raise forms.ValidationError(form_date_event.errors)
elif form_event.is_valid() and form_date_event.is_valid() and request.POST['action'] == 'update':
form_event.save()
form_date_event.save()
else:
raise forms.ValidationError([form_event.errors, form_date_event.errors])
return render(request, "events/event-edit.html", context)
dateEvent模型修改场地字段,venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)
在event_edit_view()函数中,添加如下代码行
if form_date_event.is_valid() and form_event.is_valid()
flag=False
evt_type = form_event.cleaned_data.get('type')
for form in form_date_event:
if form.cleaned_data.get('venue') is None and evt_type !="recording release":
flag = True
break
if flag:
messages.error(request,'Venue can be blank only for recording release events')
return render(request,myhtml.html,{'formset':form_date_event,'form':form_event})
else:
form_event.save()
form_date_event.save()
我想在 django 内联表单集 (form_date_event
) 中使用自定义验证,以便根据父 (form_event
) 表单上的一个值获得不同的验证。
具体来说,如果 form_event
的类型是 'recording release',我希望 form_date_event
内联格式集能够接受空位置。我怎样才能做到这一点?下面的 type = cleaned_data.get('type')
不起作用,我想是因为它获取的是表单集的 clean data
,而不是父表单的
models.py
:
class Venue(models.Model):
venue_name = models.CharField(max_length=50)
class Event(models.Model):
EV_TYPE = (
('performance', 'performance'),
('recording release', 'recording release'),
('other', 'other'),
)
title = models.CharField(max_length=200)
type = models.CharField(max_length=20, choices=EV_TYPE, default="performance")
class dateEvent(models.Model):
venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)
event = models.ForeignKey(Event, on_delete=models.CASCADE)
start_date_time = models.DateTimeField(auto_now=False, auto_now_add=False)
forms.py
:
class EventForm(forms.ModelForm):
class Meta:
model = Event
fields = [
'type',
'title',
]
views.py
:
class BaseDateEventFormSet(BaseInlineFormSet):
def clean(self):
cleaned_data = super().clean()
type = cleaned_data.get('type')
if type == 'recording release':
self.add_error('repertoire', _("This field is required"))
return cleaned_data
def event_edit_view(request, id):
event = get_object_or_404(Event, id=id)
active_user = request.user
form_event = EventForm(request.POST or None, instance=event)
DateEventFormSet = inlineformset_factory(Event, dateEvent, extra=5, can_delete=True, fields=('event', 'start_date_time', 'venue', 'link', 'link_description'),
form_date_event = DateEventFormSet(request.POST or None, instance=Event.objects.get(id=id), prefix="dateEvent", queryset=dateEvent.objects.filter(event__id=id))
context = {
'event': event,
'id': event.id,
'form_event': form_event,
'form_date_event': form_date_event,
}
if request.method == "POST":
if form_event.is_valid() and request.POST['action'] == 'submit':
if form_date_event.is_valid():
flag=False
evt_type = form_event.cleaned_data.get('type')
for form in form_date_event:
print(form.cleaned_data.get('venue'))
if form.cleaned_data.get('venue') is None and evt_type !="recording release":
flag = True
break
if flag:
messages.error(request,'Venue can be blank only for recording release events')
return render(request, "events/event-edit.html", context)
else:
form_event.save()
form_date_event.save()
return redirect('my-events')
else:
raise forms.ValidationError(form_date_event.errors)
elif form_event.is_valid() and form_date_event.is_valid() and request.POST['action'] == 'update':
form_event.save()
form_date_event.save()
else:
raise forms.ValidationError([form_event.errors, form_date_event.errors])
return render(request, "events/event-edit.html", context)
dateEvent模型修改场地字段,venue = models.ForeignKey(Venue, on_delete=models.CASCADE,null=True,blank=True)
在event_edit_view()函数中,添加如下代码行
if form_date_event.is_valid() and form_event.is_valid()
flag=False
evt_type = form_event.cleaned_data.get('type')
for form in form_date_event:
if form.cleaned_data.get('venue') is None and evt_type !="recording release":
flag = True
break
if flag:
messages.error(request,'Venue can be blank only for recording release events')
return render(request,myhtml.html,{'formset':form_date_event,'form':form_event})
else:
form_event.save()
form_date_event.save()