Django:不应用字段验证器和 UNIQUE 约束
Django: field validator and UNIQUE constraint are not applyed
我有一个带有 pat 字段的随机化模型,该模型应该是唯一的并且具有指定的格式。
我定义了 unique=true 和验证器,但都没有应用
例如,FRA-0001 应该是有效的,如果我尝试注册此代码两次,它应该会在我的表单上引发错误验证消息(但不会导致数据库崩溃)。
但是目前,我可以注册 FRA,例如,如果我注册了两次,我会引发数据库错误 UNIQUE contraint failed
models.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'
),
],
)
...
forms.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})
您在表单中将 pat
字段重新定义为 CharField
,因此应用您在模型中指定的 none 验证。您可以将表单重写为 ModelForm
或将正则表达式和唯一性验证添加到表单中。
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
我有一个带有 pat 字段的随机化模型,该模型应该是唯一的并且具有指定的格式。 我定义了 unique=true 和验证器,但都没有应用
例如,FRA-0001 应该是有效的,如果我尝试注册此代码两次,它应该会在我的表单上引发错误验证消息(但不会导致数据库崩溃)。
但是目前,我可以注册 FRA,例如,如果我注册了两次,我会引发数据库错误 UNIQUE contraint failed
models.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'
),
],
)
...
forms.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})
您在表单中将 pat
字段重新定义为 CharField
,因此应用您在模型中指定的 none 验证。您可以将表单重写为 ModelForm
或将正则表达式和唯一性验证添加到表单中。
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