以父表单中的字段值为条件验证内联表单集

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()