繁体   English   中英

Django:'唯一约束失败'

[英]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()否则您将失去唯一约束检查​​。

从文档:

https://docs.djangoproject.com/en/3.0/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

示例代码中对 super().clean() 的调用可确保维护父类中的任何验证逻辑。 如果您的表单继承了另一个未在其 clean() 方法中返回cleaned_data 字典的表单(这样做是可选的),则不要将cleaned_data 分配给super() 调用的结果,而是使用self.cleaned_data:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM