[英]Django: 'UNIQUE constraint failed'
我在 RandomisationFOrm 中覆盖了init并且有一个我以前没有的错误
我理解错误:在我的模型中 Randomization ran_num 字段是唯一的,当我尝试使用相同的 ran_num 调用 randomisation_edit 视图时尝试保存表单时,它会引发错误
但是在覆盖 __init__ 之前,这个错误是由 Django 自己管理的
我尝试添加如下验证但引发另一个错误: “RandomisationForm”对象没有属性“clean_data” ->我对其他字段执行相同操作而没有此错误...
def clean_ran_num(self):
data = self.clean_data['ran_num']
if data == 'CIV-CO-001':
raise forms.validationError('test')
return data
我尝试在全局“干净”方法中添加验证,但它不适用...
我不明白...
模型.py
class Randomisation(models.Model):
# ran_num = models.CharField("Patient code", max_length=10, unique=True, null=True, blank=True,validators=[validate_patient_code])
ran_ide = models.AutoField(primary_key=True)
ran_num = models.CharField("Patient code", max_length=10, unique=True, null=True, blank=True)
ran_dat = models.DateField("Date of randomization", null=True, blank=True)
ran_inv = models.CharField("Investigator", max_length=20, null=True, blank=True)
ran_pro = models.IntegerField("Procedure used to randomized", null=True, blank=True)
ran_pro_per = models.CharField("if telephone, name of the person reached on the phone", max_length=20, null=True, blank=True)
ran_crf_inc = models.IntegerField("Was the CRF inclusion 2 Eligibility fulfilled?", null=True, blank=True)
ran_tbc = models.IntegerField("Is TB diagnosis possible, probable or definite?", null=True, blank=True)
ran_crf_eli = models.IntegerField("Was the CRF Inclusion 2 Eligibility fulffiled?", null=True, blank=True)
ran_cri = models.IntegerField("Is the conclusion All criteria fulfilled for randomisation", null=True, blank=True)
ran_sta = models.IntegerField("British Medical Council Staging (worst stage reported between first symptoms and now)", null=True, blank=True)
ran_vih = models.IntegerField("HIV/AIDS status", null=True, blank=True)
ran_bra = models.IntegerField("TB treatment assigned", null=True, blank=True)
ran_med = models.CharField("Batch number", max_length=6, null=True, blank=True)
ran_log_dat = models.DateTimeField("Date", null=True, blank=True)
ran_log = models.CharField("Name of the person who performs randomisation on site", max_length=10, null=True, blank=True)
表格.py
class RandomisationForm(forms.ModelForm):
# surcharge méthode constructeur (__init__) pour avoir accès aux variables de sessions
# https://stackoverflow.com/questions/3778148/django-form-validation-including-the-use-of-session-data
def __init__(self, request, *args, **kwargs):
self.request = request
super(RandomisationForm, self).__init__(*args, **kwargs)
# vérification que le numéro patient saisi correspond bien au site actuellement sélectionné
# i.e. profil 'International'
def clean(self):
data = self.cleaned_data['ran_num']
if data[4:6] != self.request.session.get('selected_site'):
raise ValidationError(_('Patient code is different from the selected site'))
TYPES = [
(None, ''),
(1, _('On-line')),
(2, _('Telephon')),
]
YESNO = [
(None, ''),
(1, _('Yes')),
(0, _('No')),
]
TB = [
(None, ''),
(1, _('Possible')),
(2, _('Probable')),
(3, _('Definite')),
]
SEVERITY = [
(None, ''),
(1, _('Mild')),
(2, _('Severe')),
]
HIV = [
(None, ''),
(0, _('Negative')),
(1, _('Positive')),
]
ran_dat = forms.DateField(
label = _("Date of randomization"),
initial = datetime.datetime.now,
required = True,
)
ran_num = forms.CharField(label = _("Patient number"), required=True) # ajout
ran_inv = forms.CharField(label = _("Investigator"), required=True)
ran_pro = forms.ChoiceField(label = _("Type"), widget=forms.Select, choices=TYPES)
ran_pro_per = forms.CharField(label = _("if telephone, name of the person reached on the phone"), required=False)
ran_crf_inc = forms.ChoiceField(label = _("Was the CRF inclusion 1 TB diagnosis fulfilled?"), widget = forms.Select, choices = YESNO)
ran_crf_eli = forms.ChoiceField(label = _("Was the CRF Inclusion 2 Eligibility fulffiled?"), widget = forms.Select, choices = YESNO)
ran_tbc = forms.ChoiceField(label = _("Is TB diagnosis possible, probable or definite?"), widget = forms.Select, choices = TB)
ran_cri = forms.ChoiceField(label = _("Is the conclusion All criteria fulfilled for randomisation"), widget=forms.Select, choices = YESNO)
ran_sta = forms.ChoiceField(label = _("British Medical Council Staging (worst stage reported between first symptoms and now)"), widget = forms.Select, choices = SEVERITY)
ran_vih = forms.ChoiceField(label = _("HIV/AIDS status"), widget = forms.Select, choices = HIV)
class Meta:
model = Randomisation
# Tous les champs sauf les champs de log et les champs TB treatment et Drug batch number
fields = ('ran_num','ran_dat','ran_inv','ran_pro','ran_pro_per','ran_crf_inc','ran_tbc','ran_crf_eli','ran_cri','ran_sta','ran_vih',)
def clean_ran_crf_inc(self):
data = self.cleaned_data['ran_crf_inc']
if int(data) == 0:
raise forms.ValidationError(_("This criteria is mandatory for randomization"))
return data
def clean_ran_crf_eli(self):
data = self.cleaned_data['ran_crf_eli']
if int(data) == 0:
raise forms.ValidationError(_("This criteria is mandatory for randomization"))
return data
def clean_ran_cri(self):
data = self.cleaned_data['ran_cri']
if int(data) == 0:
raise forms.ValidationError_(("This criteria is mandatory for randomization"))
return data
视图.py
def randomisation_edit(request):
if request.method == "POST":
form = RandomisationForm(request, data=request.POST or None)
if form.is_valid():
randomisation = form.save()
# randomisation
rand = Randomiser(randomisation.ran_num, randomisation.ran_vih, randomisation.ran_sta)
# Mise à jour de la base de données -> Patient code pour rendre indisponible la ligne
# pour une prochaine randomisation
# ListeRandomisation
# 1.Récupération de la ligne dans la liste de rando
bras = rand['bras']
# 2.Mise à jour de la ligne dans la liste de rando
patient = ListeRandomisation.objects.get(ran_ide = bras)
patient.ran_dis = randomisation.ran_num # pat
patient.save()
# Medicament
# 1.Récupération de la ligne dans la liste de correspondance médicament
medicament = rand['medicament']
# 2.Mise à jour de la ligne dans la liste de correspondance médicament
medicament = Medicament.objects.get(med_ide = medicament)
medicament.ran_dis = randomisation.ran_num # pat
medicament.save()
# mise à jour de la variable de session can_randomize
request.session['can_randomize'] = is_randomizable(medicament.ran_dis)
# Mise à jour de la table Randomisation avec le bras et le numéro de boite attribués
randomisation.ran_bra = patient.ran_bra
randomisation.ran_med = medicament.med_num
randomisation.ran_log_dat = datetime.now()
randomisation.ran_log = request.user.username
randomisation.save()
return redirect('randomization:confirmation', pk = randomisation.pk)
else:
form = RandomisationForm(request)
return render(request, 'randomization/randomisation_edit.html', {'form': form})
当您覆盖 Form.clean 方法时,您必须调用super(RandomisationForm, self).clean()
否则您将失去唯一约束检查。
从文档:
示例代码中对 super().clean() 的调用可确保维护父类中的任何验证逻辑。 如果您的表单继承了另一个未在其 clean() 方法中返回cleaned_data 字典的表单(这样做是可选的),则不要将cleaned_data 分配给super() 调用的结果,而是使用self.cleaned_data:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.