Opened 5 years ago

Closed 5 years ago

Last modified 5 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, 5 years ago

Component: Database layer (models, ORM) → Forms
Resolution: → invalid
Status: new → closed

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, 5 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, 5 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