Django必须至少填写一个表单字段

2024-09-30 14:27:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在学习使用django1.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)
....

这是我的表格代码:

^{pr2}$

这是关于表单.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>

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


Tags: andinselftrueifmodelsvisacd
2条回答

工作解决方案如下:

    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

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

可能有一些Django细节可以帮助您,但是我建议您首先考虑Python。在

对于第一个任务,我认为您可能会从filter中受益。在

首先,我们需要您要检查的值的列表:

values_we_care_about = ['nationality_visa_country_of_birth'
                        'nationality_visa_citizenship'
                        'nationality_visa_residency'
                        'nationality_visa_work_visa',
                         etc.]

下一步,我们需要把你用来检查东西的逻辑提炼成一个简单的函数

^{pr2}$

现在,我们可以使用这个函数来过滤所有值(如果您使用Python2,它将立即返回一个列表,但是如果您使用Python3,您将得到一个生成器;我假设Python2):

checked_values = filter(checking_stuff_function, values_we_care_about)

现在,我们可以检查有多少checked_values通过了。你可能已经知道这是怎么回事了。。。在

if len(checked_values) < 1:
   # There's an error!

现在,您只需要重置表单(因为我们之前使用了过滤器,为什么不在这里使用map)呢?)公司名称:

map(lambda val: del self.cleaned_data[val], values_we_care_about]

不过,我从来没有用过表格。真的有必要在重写的clean方法中删除它们吗?在视图中不能更好地处理这个问题吗?我会让别人来回答。在

之后你就可以把表格还给我了。在

编辑

我忘了你的错误。这也可以用一种类似于我们在这里所做的方式来完成,所以我不想详细说明。在

你的原始代码所缺少的基本原则是:“不要重复你自己”。试着在你所做的事情中找到共同的模式,并利用这些模式来发挥你的优势。如果您在三到四个地方编写相同的字符串数组,这是一个问题。将它们保存到一个列表中,然后对它们进行迭代。要读的代码要少得多。在

相关问题 更多 >