#35578 closed Uncategorized (invalid)
Customizing `username_validator` in custom User model extending `django.contrib.auth.models.AbstractUser` doesn't work
Reported by: | Oscar Rovira | Owned by: | |
---|---|---|---|
Component: | contrib.auth | Version: | 5.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Hi there!
I'm sorry if that is the expected behaviour of what I'm going to report, but looking at the implementation, it should work as I expected.
I have my own authentication User
model, extending from AbstracUser
. Looking at the code of AbstractUser
, one may think that defining the class prop username_validator
, the validation of the username at all the levels (createsuperuser command, Admin create user form, User.objects.create_user, ...) should use the new validator provided in the customized class. It is not working like that. In order to make it work, one has to re-define also the username
field in the customized model.
So, I have the following:
@deconstructible class CustomUnicodeUsernameValidator(validators.RegexValidator): """Overrides the default username validator from Django Abstract User to avoid usernames with characters '@', '+' or '.' """ regex = r"^[\w-]+\Z" message = _( "Enter a valid username. This value may contain only letters, " "numbers, and -/_ characters." ) flags = 0 ... class User(AbstractUser): """Main app user, extending default Django users.""" # overriding the one defined in AbstractUser username_validator = CustomUnicodeUsernameValidator() # type: ignore # Other custom fields ...
and it does not work, the custom username_validator is not being used.
However, if I redefine the username
field, including the validators=[username_validator]
attribute, it works as expected.
As I said, maybe it is the expected behaviour, and it's just a lack of documentation.
Thanks!
Change History (2)
comment:1 by , 6 months ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
comment:2 by , 6 months ago
Thanks for the clarification Natalia. I guess that I misunderstood the point about "if you want to add some additional profile information (fields)", because I want it, keeping the username
field and just modifying the validator. Now everything makes sense.
Hello Oscar, thank you for your report. What you are describing is explained by how Python class definition works, this is not about Django. See this simpler example:
In this example, the class attribute
username
is defined (and "calculated") at class definition time and is not something "dynamic" that you can expect it to be "recalculated" in children, if you don't override it.Having said the above, please also note that the user customization docs indicate that if you wish to customize the
User
model, ideally you would extendAbstractBaseUser
. Specifically AbstractUser should be used when adding more fiels, not changing existing fields behavior:So this means that if you are extending
AbstractUser
, the default username validation should suffice for your case. If it does not suffice, then perhaps you should consider extendingAbstractBaseUser
and building your own validator and custom username field as your business logic requires.Because of the above, this report seems better suited to be a support request. The best place to get more answers to your issue is using any of the user support channels from this link. Since the goal of this issue tracker is to track issues about Django itself, and your issue seems, at first, to be located in your custom code, I'll be closing this ticket as invalid following the ticket triaging process.