Django:“唯一约束失败”

时间:2019-12-19 16:51:59

标签: django unique-constraint

我在RandomizationFOrm中覆盖了 init ,并且遇到了以前从未遇到过的错误

我了解错误:在我的模型中,randomization ran_num字段是UNIQUE 当我尝试使用相同的ran_num调用randomisation_edit视图时尝试保存表单时,会引发错误

,但在覆盖__init__之前,此错误由Django本身管理

我尝试如下添加验证,但引发另一个错误:'RandomisationForm'对象没有属性'clean_data'->对于其他字段,我也执行相同操作,而没有出现此错误...

  val clusterLabel = pipelineModel.transform(data).
  select("cluster", "label").as[(Int, String)]
  val weightedClusterEntropy = clusterLabel.
   groupByKey { case (cluster, _) => cluster }.
   mapGroups { case (_, clusterLabels) =>
  val labels = clusterLabels.map { case (_, label) => label }.toSeq
  val labelCounts = labels.groupBy(identity).values.map(_.size)

我尝试在全局“干净”方法中添加验证,但是它不适用...

我不明白...

models.py

def clean_ran_num(self):
    data = self.clean_data['ran_num']
    if data == 'CIV-CO-001':
       raise forms.validationError('test')
    return data

forms.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)


views.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

1 个答案:

答案 0 :(得分:0)

当您重写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代替: