Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#33591 closed Bug (invalid)

Incorrect validation message

Reported by: Maria Sorokina Owned by: nobody
Component: Forms Version: 4.0
Severity: Normal Keywords: ValidationError, validation, message
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Hello!

What I did: I've created a model and added a clean method to it to validate two fields together. I've created a dictionary of errors, and raised ValidationError with that dictionary as an argument. I've checked creating new model in standard admin site.

What I expected to see: when I have an error I should see a message "Test1".

What I got: I see error message "Enter a whole number.".

What I noticed: if I remove code="invalid" parameter then I get the correct message "Test1".

My code:

from django.db import models
from django.core.exceptions import ValidationError
from django.core.validators import MinValueValidator, MaxValueValidator


class Confidant(models.Model):

    CALENDARS = (
        ('L', 'Lunar'),
        ('G', 'Gregorian'),
        ('J', 'Julian'),
    )
    
    MONTHS = (
        (1, 'January'),
        (2, 'February'),
        (3, 'March'),
        (4, 'April'),
        (5, 'May'),
        (6, 'June'),
        (7, 'July'),
        (8, 'August'),
        (9, 'September'),
        (10, 'October'),
        (11, 'November'),
        (12, 'December'),
    )

    id = models.BigAutoField(primary_key=True)
    height = models.PositiveSmallIntegerField(
        validators=[
            MinValueValidator(130),
            MaxValueValidator(210),
        ],
    )
    birth_month = models.PositiveSmallIntegerField(choices=MONTHS)
    birth_day = models.PositiveSmallIntegerField(
        validators=[
            MinValueValidator(1),
            MaxValueValidator(31),
        ],
    )
    calendar = models.CharField(max_length=1, choices=CALENDARS)

    def clean(self):
        errors = {}
        if (
            self.birth_month == 2 and self.birth_day > 29
            or self.birth_month in [4,6,9,11] and self.birth_day > 30
        ):
            #errors['birth_day'] = ValidationError('Test1') #shows correct message
            errors['birth_day'] = ValidationError('Test1', code='invalid') #shows wrong message
        if errors:
            raise ValidationError(errors)

Change History (3)

comment:1 by Mariusz Felisiak, 2 years ago

Component: Database layer (models, ORM)Forms
Resolution: invalid
Status: newclosed

Validation error messages defined at the model level are always override with those defined on the form fields, see docs. forms.IntegerField has already defined an invalid error message.

in reply to:  1 ; comment:2 by Maria Sorokina, 2 years ago

Replying to Mariusz Felisiak:

Validation error messages defined at the model level are always override with those defined on the form fields, see docs. forms.IntegerField has already defined an invalid error message.

Thank you for your reply! Even in spite of your comment a couple of things still confuse me:

  1. I understood the part about overriding model validation with form validation. What I cannot understand is why would I get an error message "Enter a whole number" when I enter the whole number. I understand that this is a default message but it doesn't make much sense to me.
  1. I've read some docs before coming here. There are some good practices regarding code parameter on this web page. So I made a conclusion that it's better to give this parameter to the ValidationError function, but I didn't find any information in the docs about how I should use this argument properly, so I just followed the examples which led me to the described situation. I would be grateful if you could provide more information about the parameter in the docs.

I am very sorry if I wasted your time, I just want to be sure that other users won't be confused as I am now.
Best wishes.

in reply to:  2 comment:3 by Mariusz Felisiak, 2 years ago

Thank you for your reply! Even in spite of your comment a couple of things still confuse me:

  1. I understood the part about overriding model validation with form validation. What I cannot understand is why would I get an error message "Enter a whole number" when I enter the whole number. I understand that this is a default message but it doesn't make much sense to me.

Because you manually raised a ValidationError in clean() with code=invalid, the error message for this exception has been replaced (as documented) with the invalid's error message defined in forms.IntegerField. If you're having trouble understanding how Django works, see TicketClosingReasons/UseSupportChannels for ways to get help.

Note: See TracTickets for help on using tickets.
Back to Top