Python Django:如何覆盖 MultipleChoiceField 的验证

2023-12-31

我试图在 Charfield 上保存多个复选框选择,但我无法绕过该消息:

选择一个有效的选择。 ['...', '...', '...'] 不是其中之一 可用的选择。

我想将选定的值与管道分隔值保存在数据库的单个属性中。我已经为 2 个 MultipleChoiceFields 创建了“clean”方法,但似乎错误是在 clean 本身之后发生的。检查结果字符串是否存在于可能值列表中。这就是我想要覆盖的。这是我正在使用的代码:

estomatology_form.py

class EstomatologiaForm(forms.ModelForm):
    sinais_e_sintomas_locais = forms.MultipleChoiceField(
        choices=Estomatologia.TIPOS_SINAIS_E_SINTOMAS,
        widget=forms.CheckboxSelectMultiple(),
        label='Sinais e Sintomas locais (marque todas as opções válidas) *',
    )
    ...

    def __init__(self, *args, **kwargs):
        if 'instance' in kwargs:
        if kwargs['instance'] is not None:
            kwargs['initial'] = {}
            ssl = kwargs['instance'].sinais_e_sintomas_locais.split('|')
            cp = kwargs['instance'].comorbidades_paciente.split('|')
            kwargs['initial']['sinais_e_sintomas_locais'] = ssl 
            kwargs['initial']['comorbidades_paciente'] = cp
        super(EstomatologiaForm, self).__init__(*args, **kwargs)

        #OBS: campos para MultipleChoiceField não devem receber esses valores em 'class'.
        #Do contrario os checkbox não são desenhados corretamente
        for field_name in self.fields:
            if field_name != "sinais_e_sintomas_locais" and field_name != "comorbidades_paciente":
                self.fields[field_name].widget.attrs.update({
                    'class': 'form-control form-dinamico',
                })

    def clean_sinais_e_sintomas_locais(self):
        import ipdb
        ipdb.set_trace()
        ssl = self.cleaned_data['sinais_e_sintomas_locais']
        self.cleaned_data['sinais_e_sintomas_locais'] = '|'.join(ssl)
        return self.cleaned_data['sinais_e_sintomas_locais']

    def clean_comorbidades_paciente(self):
        import ipdb
        ipdb.set_trace()
        cp = self.cleaned_data['comorbidades_paciente']
        self.cleaned_data['comorbidades_paciente'] = '|'.join(cp)
        return self.cleaned_data['comorbidades_paciente']

    def save(self, *args, **kwargs):
        import ipdb
        ipdb.set_trace()
        instance = super(EstomatologiaForm, self).save(*args, **kwargs)
        instance.sinais_e_sintomas_locais = self.cleaned_data['sinais_e_sintomas_locais']
        instance.comorbidades_paciente = self.cleaned_data['comorbidades_paciente']
        instance.save()
        return instance

模型.py

...
sinais_e_sintomas_locais = models.CharField(
    blank=False, choices=TIPOS_SINAIS_E_SINTOMAS, max_length=255,
    verbose_name="Sinais e Sintomas locais (marque todas as opções \
    válidas) *",
)
...

and here is a printscreen of the error: enter image description here

错误消息的意思是:“选择一个有效的选项。drenagem_pus|nenhum_dos_anteriores 不是可用的选项之一。”


在你的模型中 - 你正在使用......

sinais_e_sintomas_locais = models.CharField(
    blank=False, choices=TIPOS_SINAIS_E_SINTOMAS, max_length=255,
    verbose_name="Sinais e Sintomas locais (marque todas as opções \
    válidas) *",
)

...并且有choices=TIPOS_SINAIS_E_SINTOMAS仅在单个选择的情况下才有效,但是当您尝试用管道分隔多个选择时,它们将无法匹配并导致验证错误。

解决办法:去掉choices=选项。虽然 - 你应该检查所有值是否都是有效的选择在你的clean_<field>方法before管道分隔它们并将其保存为CharField, eg:

def clean_sinais_e_sintomas_locais(self):
    ssl = self.cleaned_data['sinais_e_sintomas_locais']
    # Check there are no selections or only valid selections
    if not (ssl or set(ssl).difference(TIPOS_SINAIS_E_SINTOMAS)):
        self.cleaned_data['sinais_e_sintomas_locais'] = '|'.join(ssl)
        return self.cleaned_data['sinais_e_sintomas_locais']
    # Error: some individual values weren't valid...
    raise forms.ValidationError('some message')
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python Django:如何覆盖 MultipleChoiceField 的验证 的相关文章

随机推荐