首页 > 解决方案 > 根据用户在 Django 表单中选择的动态必填字段

问题描述

我想让两个字段(曲目和表演者)仅在用户选择并提交 type="performance" 时才需要。这是我的模型:

class Event(models.Model):

    EV_TYPE = (
        ('performance', 'performance'),
        ('other', 'other'),
    )

    title = models.CharField(max_length=200)
    type = models.CharField(max_length=15, choices=EV_TYPE, default="performance")
    repertoire = models.ManyToManyField(Work, blank=True)
    performer = models.ManyToManyField(Profile, limit_choices_to={'role__type__contains': 'Performer'})

我的表格:

class EventForm(forms.ModelForm):

    class Meta:
        model = Event
        fields = [
            'type',
            'submitted_by',
            'title',
            'repertoire',
        ]

我的观点:

def event_create_view(request):

if request.method == 'POST':
    form_event = EventForm(
        request.POST,
        repertoire_required=(not (active_user.id == 17)), # if the user is NMS then the repertoire field is not compulsory
        initial={'submitted_by' : active_user.profile.id}
        )
    form_venue = AddVenueForm()
    form_profile = ProfileForm()
    form_work = WorkFromEventForm()

    if form_event.is_valid():

        this_event = form_event.save()
        return redirect('event-edit', id=this_event.id)

这是我尝试过的。在上面的“form_event.is_valid”中,我做了:

    if form_event.is_valid():


        this_event = form_event.save(commit=False)
        if this_event['type'] == 'performance' and this_event['performer'] and this_event['repertoire']:
            this_event.save()
            return redirect('event-edit', id=this_event.id)

但这不起作用(当我提交时,我仍然会收到“此字段是必需的”)。我怎样才能实现我想做的事情?

附录

这也不起作用:

if 

this_event['type'] == 'performance' and not this_event['performer'] or not this_event['repertoire']:
                messages.error(request, form_event.errors)
            else:
                this_event.save()
                

标签: djangodjango-viewsdjango-forms

解决方案


您可以使用clean表单上的方法来执行此操作。

例如,您可能会这样做;

def clean(self):
    """
    Validate the form input
    """
    cleaned_data = super().clean()
    type = cleaned_data.get('type')

    if type == 'performance':
        repertoire = cleaned_data.get('repertoire')
        performer = cleaned_data.get('performer')
        if not repertoire:
            self.add_error('repertoire', _("This field is required"))
        if not performer:
            self.add_error('performer', _("This field is required"))

    return cleaned_data

表单验证的文档在这里;https://docs.djangoproject.com/en/3.1/ref/forms/validation/


推荐阅读