Skip to main content
 首页 » 编程设计

python之django之必须至少填写一个表单字段

2025年05月04日36pander-it

我正在学习使用 Django 1.4(我会在 1.7 发布后立即升级)。

我有一个测试表单,其中我已将所有字段标记为 required=False,但我需要让用户在表单上至少输入一个字段。输入哪个字段并不重要,只要至少输入一项即可。

我确实有一个可行的解决方案,但我认为这可以做得更好,所以我希望对 Django 有更好理解的人可以向我展示更好的解决方案。

这是我的模型代码:

.... 
nationality_visa_country_of_birth = models.TextField(null=True, blank=True) 
nationality_visa_citizenship = models.TextField(null=True, blank=True) 
nationality_visa_residency = models.TextField(null=True, blank=True) 
nationality_visa_work_visa = models.TextField(null=True, blank=True) 
nationality_visa_study_visa = models.TextField(null=True, blank=True) 
nationality_visa_specialist_visa = models.TextField(null=True, blank=True) 
nationality_visa_other_visa = models.TextField(null=True, blank=True) 
nationality_visa_current_valid_passport_display_type = models.PositiveIntegerField(default=0) 
nationality_visa_multiple_passports = models.BooleanField(default=False) 
nationality_visa_passport_nationality = models.TextField(null=True, blank=True) 
nationality_visa_timestamp_added = models.DateTimeField(auto_now_add=True, auto_now=False) 
nationality_visa_timestamp_updated = models.DateTimeField(auto_now=True, auto_now_add=False) 
.... 

这是我的表单代码:

nationality_visa_country_of_birth = forms.CharField(label=_('Country of Birth'), max_length=250, required=False) 
nationality_visa_citizenship = forms.CharField(label=_('Citizenship'), max_length=250, required=False) 
nationality_visa_residency = forms.CharField( label=_('Residency'), max_length=250, required=False) 
nationality_visa_work_visa = forms.CharField( label=_('Work Visa'), max_length=250, required=False) 
nationality_visa_study_visa = forms.CharField( label=_('Student Visa'),max_length=250, required=False) 
nationality_visa_specialist_visa = forms.CharField(label=_('Specialist Visa'), max_length=250, required=False) 
nationality_visa_other_visa = forms.CharField(label=_('Other Visa'), max_length=250, required=False) 
nationality_visa_current_valid_passport_display_type = forms.TypedChoiceField(coerce=int, label=_('Current Valid Passport'), choices=[(x, x) for x in range(0, 3)], required=False) 
nationality_visa_multiple_passports = forms.BooleanField( label=_('Multiple Passports'), required=False, help_text=_("Select this option if you're going to enter multiple passport details into the field below.")) 
nationality_visa_passport_nationality = forms.CharField( label=_('Nationality of Passport(s)'), max_length=250, required=False) 

这是要求用户至少输入一个字段的 forms.py 上的验证数据:

def clean(self): 
 
    cd_nvdf = super(NationalityVisaDetailsForm, self).clean() 
 
    if 'nationality_visa_country_of_birth' in cd_nvdf and len(cd_nvdf['nationality_visa_country_of_birth'].strip()) == 0: 
        if 'nationality_visa_citizenship' in cd_nvdf and len(cd_nvdf['nationality_visa_citizenship'].strip()) == 0: 
            if 'nationality_visa_residency' in cd_nvdf and len(cd_nvdf['nationality_visa_residency'].strip()) == 0: 
                if 'nationality_visa_work_visa' in cd_nvdf and len(cd_nvdf['nationality_visa_work_visa'].strip()) == 0: 
                    if 'nationality_visa_study_visa' in cd_nvdf and len(cd_nvdf['nationality_visa_study_visa'].strip()) == 0: 
                        if 'nationality_visa_specialist_visa' in cd_nvdf and len(cd_nvdf['nationality_visa_specialist_visa'].strip()) == 0: 
                            if 'nationality_visa_other_visa' in cd_nvdf and len(cd_nvdf['nationality_visa_other_visa'].strip()) == 0: 
                                if 'nationality_visa_current_valid_passport_display_type' in cd_nvdf and cd_nvdf['nationality_visa_current_valid_passport_display_type'] == 0: 
                                    if 'nationality_visa_passport_nationality' in cd_nvdf and len(cd_nvdf['nationality_visa_passport_nationality'].strip()) == 0: 
 
                                        self._errors['nationality_visa_country_of_birth'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
                                        self._errors['nationality_visa_citizenship'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_residency'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_work_visa'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_study_visa'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_specialist_visa'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_other_visa'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_current_valid_passport_display_type'] = self.error_class([_(" ")]) 
                                        self._errors['nationality_visa_passport_nationality'] = self.error_class([_(" ")]) 
 
                                        del self.cleaned_data['nationality_visa_country_of_birth'] 
                                        del self.cleaned_data['nationality_visa_citizenship'] 
                                        del self.cleaned_data['nationality_visa_residency'] 
                                        del self.cleaned_data['nationality_visa_work_visa'] 
                                        del self.cleaned_data['nationality_visa_study_visa'] 
                                        del self.cleaned_data['nationality_visa_specialist_visa'] 
                                        del self.cleaned_data['nationality_visa_other_visa'] 
                                        del self.cleaned_data['nationality_visa_current_valid_passport_display_type'] 
                                        del self.cleaned_data['nationality_visa_passport_nationality'] 
 
    return cd_nvdf 

目前通过验证的表单会高亮上面的表单域,但是对于模板上的每个表单域,都会在html代码中插入如下html代码,使得每个表单域下面多出一个换行符:

<span class="help-inline"> 
    <strong> 
        <br> 
    </strong> 
</span> 

我如何更好地编写验证代码,以便用户至少输入一个表单字段和/或不包括上面显示的额外换行代码?

请您参考如下方法:

这是有效的解决方案:

    def clean(self): 
    cd_nvdf = super(NationalityVisaDetailsForm, self).clean() 
 
    if not any( 
        cd_nvdf.get(x, '') 
        for x in ( 
            'nationality_visa_country_of_birth', 
            'nationality_visa_citizenship', 
            'nationality_visa_residency', 
            'nationality_visa_work_visa', 
            'nationality_visa_study_visa', 
            'nationality_visa_specialist_visa', 
            'nationality_visa_other_visa', 
            'nationality_visa_current_valid_passport_display_type', 
            'nationality_visa_passport_nationality', 
        ) 
    ): 
 
        self._errors['nationality_visa_country_of_birth'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_citizenship'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_residency'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_work_visa'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_study_visa'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_specialist_visa'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_other_visa'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_current_valid_passport_display_type'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
        self._errors['nationality_visa_passport_nationality'] = self.error_class([_("You must enter at least one Nationality & Visa Detail.")]) 
 
    return cd_nvdf 

我希望这会对某人有所帮助。