Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

django - IntegrityError (wrong) instead of ValidationError (correct)

Django Version: 3.1.5

Python Version: 3.6.9

Model

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])

Form

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 = []

Admin

class GoogleAnalyticsAdmin(admin.ModelAdmin):
    form = CounterForm


admin.site.register(GoogleAnalytics, GoogleAnalyticsAdmin)

Traceback

https://dpaste.com/6CUL2VZAW

Well, unique constraint for counter field worked.

But I extected a validation error rather than IntegrityError. Could you tell me how to fix that?

question from:https://stackoverflow.com/questions/65869639/integrityerror-wrong-instead-of-validationerror-correct

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think your problem is that you've overridden clean method and you didn't call it's dependencies. Because clean of your super model form validate your unique constraints before hitting and writing a new record in database. So I think adding the line super().clean() to your clean method should solve your problem.

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

Or if you want to check your condition before super conditions you can move super().clean() to last line of your clean method.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...