【发布时间】:2021-06-26 01:34:11
【问题描述】:
我想在 django 内联表单集 (form_date_event) 中使用自定义验证,以便根据父 (form_event) 表单上的一个值获得不同的验证。
具体来说,如果form_event 的类型是“录音发布”,我希望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)
【问题讨论】:
-
接受空场地是什么意思?你是说
None? -
我的意思是用户只填写/提交
start_date并保持venue字段不变。 -
这必须在 view 中完成,因为您想使用两个表单来执行验证。
-
@Neeraj 这确实是我想要做的。正如您从我的问题中看到的那样,我说视图中的
type = cleaned_data.get('type')并没有做到这一点。我需要从其他表单中获取type。怎么样? -
代码必须写在 event_edit_view() 函数中
标签: django django-views django-forms