Django:字段验证器和UNIQUE约束没有被应用。

问题描述 投票:0回答:1

我有一个随机化模型,它的pat字段应该是唯一的,并且有一个指定的格式。

例如,FRA-0001应该是有效的,如果我尝试注册这个代码两次,它应该会在我的表单上发出一个错误的验证信息(但不会使数据库崩溃)。

但目前,我可以注册FRA,例如,如果我注册了两次,就会出现数据库错误UNIQUE contraint failed。

模型.py

class Randomisation(models.Model):

    ...
    pat = models.CharField("Patient number", max_length=8, unique=True, null=True, blank=True,
        validators = [
            RegexValidator(
                regex='^[A-Z]{3}-[0-9]{4}$',
                message= 'L\'identifiant doit être au format XXX-0000',
                code='invalid_participant_id'
            ),
        ],
    )
...

窗体.py

class RandomizationEditForm(forms.Form):

    def __init__(self, request, *args, **kwargs):
        super(RandomizationEditForm, self).__init__(*args, **kwargs)
        self.user_country = Pays.objects.get(pay_ide = request.session.get('user_country'))
        # self.language = request.session.get('language')
        # print(self.language)
        self.user_site_type = request.session.get('user_site_type')        
        PAYS = Pays.options_list(self.user_country,self.user_site_type,'fr')
        SEXE = Thesaurus.options_list(2,'fr')
        STRATE_1 = Thesaurus.options_list(3,'fr')
        STRATE_2 = Thesaurus.options_list(4,'fr')
        YES = [(None,''),(0,'Non'),(1,'Oui'),]

        self.fields["pat"] = forms.CharField(label = "Numéro patient (XXX-0000)")
        self.fields['pat'].widget.attrs.update({
            'autocomplete': 'off'
        })
        self.fields["ran_nai"] = forms.IntegerField(label = "Date de naissance (année)", widget=forms.TextInput)
        self.fields['ran_nai'].widget.attrs.update({
            'autocomplete': 'off'
        })
        self.fields["ran_sex"] = forms.ChoiceField(label = "Sexe", widget=forms.Select, choices=SEXE)
        self.fields["ran_st1"] = forms.ChoiceField(label = "Gravité de la maladie COVID-19", widget=forms.Select, choices=STRATE_1)
        self.fields["ran_bug"] = forms.BooleanField(label = "Recours à la procédure de secours ?", required = False)
        self.fields["ran_dem_nom"] = forms.CharField(label = "Nom de la personne qui demande la randomisation", required = False, initial=None)
        self.fields['ran_dem_nom'].widget.attrs.update({
            'autocomplete': 'off'
        })
        self.fields["ran_dem_dat"] = forms.DateField(
            # input_formats=settings.DATE_INPUT_FORMATS,
            label = "Date de la demande",
            initial = timezone.now(),
            required = False,
            )
        self.fields['ran_dem_dat'].widget.attrs.update({
            'autocomplete': 'off'
        })

    # def clean_pat(self):
    #     data = self.cleaned_data['pat']
    #     if len(data) < 8:
    #         raise forms.ValidationError("Merci de contrôler la numéro patient")
    #     return data

    def clean_ran_nai(self):
        data = self.cleaned_data['ran_nai']
        if data > 2003:
            raise forms.ValidationError("Merci de contrôler la date de naissance")
        return data

    def clean_ran_dem_dat(self):
        data = self.cleaned_data['ran_dem_dat']
        entrydate = datetime.datetime.strptime(str(data), "%Y-%m-%d")
        currentdate = datetime.datetime.now()
        if entrydate > currentdate:
            raise forms.ValidationError("Merci de contrôler la date (postérieure à la date du jour)")
        return data

views.py

def randomization_edit(request):

    if request.method == "POST":
        form = RandomizationEditForm(request, data=request.POST or None)
        if form.is_valid():
            # Récupération des données permettant la randomisation  
            randomisation = Randomisation.objects.filter(Q(pay_ide=form.data.get('pay_ide')) & Q(ran_act=1) & Q(ran_st1=form.data.get('ran_st1')) & Q(pat=None)).first()

            randomisation.pat = form.cleaned_data['pat']
            randomisation.ran_nai = form.data.get('ran_nai')
            randomisation.ran_sex = form.data.get('ran_sex')
            randomisation.ran_bug = form.cleaned_data['ran_bug']
            if form.data.get('ran_dem_nom') == '':
                randomisation.ran_dem_nom = None
            else:
                randomisation.ran_dem_dat = form.data.get('ran_dem_dat')
            randomisation.ran_log = request.user.username
            randomisation.ran_dat = timezone.now()
            randomisation.save()

            return redirect('randomization:confirmation', pk = randomisation.pk)

    else:
        form = RandomizationEditForm(request)

    return render(request, 'randomization/edit.html', {'form': form})
django unique
1个回答
1
投票

你重新定义了 pat 场作为 CharField 中的表单,所以你在模型上指定的验证都不适用。你可以重写你的表单,使其成为一个类似于 ModelForm 或在您的表单中添加regex和唯一性验证。

class RandomizationEditForm(forms.Form):

    def __init__(self, *args, **kwargs):
       super(RandomizationEditForm, self).__init__(*args, **kwargs)

       self.fields["pat"] = forms.CharField(label = "Numéro patient (XXX-0000)", validators=[RegexValidator(
            regex='^[A-Z]{3}-[0-9]{4}$',
            message= 'L\'identifiant doit être au format XXX-0000',
            code='invalid_participant_id'
        )])

    def clean_pat(self):
       data = self.cleaned_data['pat']
       if Randomisation.objects.filter(pat=data).exists():
           raise forms.ValidationError("L\'identifiant doit être unique")
       return data
© www.soinside.com 2019 - 2024. All rights reserved.