【问题标题】:IntegrityError (wrong) instead of ValidationError (correct)IntegrityError(错误)而不是 ValidationError(正确)
【发布时间】:2021-01-24 10:48:41
【问题描述】:

Django 版本:3.1.5

Python 版本:3.6.9

型号

class GoogleAnalytics(models.Model):
    counter = models.SlugField(max_length=17,
                               null=False,
                               default="",
                               unique=True,
                               verbose_name="Counter")

    tracking_code = models.TextField(null=False,
                                     default="",
                                     verbose_name="Tracking code",
                                     validators=[validate_google_analytics_tracking_code])

表格

class CounterForm(forms.ModelForm):
    """
    Validate if the value in counter field
    really corresponds to the tracking code for this counter.
    """

    def clean(self):
        counter_manager = CounterManager()
        if "GoogleAnalytics" in str(self.Meta.model):
            counter_from_tracking = counter_manager.get_counter(self.cleaned_data['tracking_code'],
                                                                Counters.GOOGLE_ANALYTICS)
        else:
            assert "YandexMetrika" in str(self.Meta.model)
            counter_from_tracking = counter_manager.get_counter(self.cleaned_data['tracking_code'],
                                                                Counters.YANDEX_METRIKA)
        if self.cleaned_data['counter'] != counter_from_tracking:
            raise ValidationError("Код не соответствует счетчику")

        return self.cleaned_data

    class Meta:
        model = GoogleAnalytics
        exclude = []

管理员

class GoogleAnalyticsAdmin(admin.ModelAdmin):
    form = CounterForm


admin.site.register(GoogleAnalytics, GoogleAnalyticsAdmin)

追溯

https://dpaste.com/6CUL2VZAW

好吧,计数器字段的唯一约束起作用了。

但我检测到的是验证错误而不是 IntegrityError。你能告诉我如何解决这个问题吗?

【问题讨论】:

    标签: django django-forms django-admin


    【解决方案1】:

    我认为您的问题是您已经覆盖了 clean 方法并且您没有将其称为依赖项。因为清理您的超级模型表单会在点击并在数据库中写入新记录之前验证您的唯一约束。因此,我认为将 super().clean() 行添加到您的 clean 方法应该可以解决您的问题。

    def clean(self):
        super().clean()
        counter_manager = CounterManager()
        if "GoogleAnalytics" in str(self.Meta.model):
            counter_from_tracking = counter_manager.get_counter(self.cleaned_data['tracking_code'],
                                                                Counters.GOOGLE_ANALYTICS)
        else:
            assert "YandexMetrika" in str(self.Meta.model)
            counter_from_tracking = counter_manager.get_counter(self.cleaned_data['tracking_code'],
                                                                Counters.YANDEX_METRIKA)
        if self.cleaned_data['counter'] != counter_from_tracking:
            raise ValidationError("Код не соответствует счетчику")
    
        return self.cleaned_data
    

    或者,如果您想在 super 条件之前检查您的条件,您可以将 super().clean() 移动到您的 clean 方法的最后一行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-31
      • 1970-01-01
      • 1970-01-01
      • 2017-12-21
      • 2022-07-13
      • 2020-04-21
      • 2013-05-07
      • 1970-01-01
      相关资源
      最近更新 更多