Python Django:如何在MultipleChoiceField上覆盖验证 [英] Python Django: how to override validation on MultipleChoiceField

查看:38
本文介绍了Python Django:如何在MultipleChoiceField上覆盖验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to save multiple checkbox selections on a Charfield, but I cannot bypass the message:

选择一个有效的选择.['...','...','...']不是以下内容之一可用的选择.

Select a valid choice. ['...', '...', '...'] is not one of the available choices.

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

I want to save the selected values with pipe separed values in a single attribute in the database. I have already created "clean" methods for the 2 MultipleChoiceFields, but it seems the error occurs AFTER the clean itself. There is a check if the resulting string is present in the list os possible values. That is what I want to override. Here is the code I'm using:

estomatologia_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

models.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:

错误消息的意思是:选择一个有效的选择.drenagem_pus | nenhum_dos_anteriores不是可用的选择之一."

The error message means: "Select a valid choice. drenagem_pus|nenhum_dos_anteriores is not one of the available choices."

推荐答案

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

In your models - you're using...

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 ,该选项仅在单个选择的情况下起作用,但是如果您尝试用管道分隔多个选择,它们将无法匹配并导致验证错误.

... and have choices=TIPOS_SINAIS_E_SINTOMAS which'll work in the event of only a single selection, but where you try to pipe delimit multiple selections, they'll fail to match and cause the validation error.

解决方案:删除 choices = 选项.虽然-您应该先在 clean_< field> 方法 中对所有值进行有效选择检查,然后再用管道将它们定界并将其另存为 CharField ,例如:

Solution: remove the choices= option. Although - you should check that all values are valid choices in your clean_<field> methods before pipe delimiting them and saving it as a 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')

这篇关于Python Django:如何在MultipleChoiceField上覆盖验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆