Opened 4 years ago
Closed 4 years ago
#32396 closed Bug (duplicate)
UsernameField normalisation throws TypeError if the username is empty
Reported by: | Łukasz Rzepa | Owned by: | |
---|---|---|---|
Component: | contrib.auth | Version: | 3.1 |
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 guys, this is my first ticket so excuse me if it's not perfect.
I'm working on a project where we use custom User
using email
as a USERNAME_FIELD
. We allow users to have custom usernames but we don't require them so username
field has null=True
.
While editing one of the staff users through the admin panel I've stumbled upon an error when leaving the username
field empty:
TypeError normalize() argument 2 must be str, not None
To register User
model to admin I'm using:
@admin.register(User) class UserAdminView(UserAdmin): add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'password1', 'password2'), }), )
The source of the problem is the fact that unicodedata.normalize()
in
class UsernameField(forms.CharField): def to_python(self, value): return unicodedata.normalize('NFKC', super().to_python(value))
needs a second argument to be a string. As super().to_python(value)
is actually forms.CharField.to_python()
''
value is returned as self.empty_value
with defaults to ''
but for a situation where CharField
has null=True
. In this case it's determined in django.db.models.fields.CharField.formfield()
that
if self.null and not connection.features.interprets_empty_strings_as_nulls: defaults['empty_value'] = None
and our self.empty_value
becomes None
which is in effect passed to normalize as a second argument.
My proposition is to fix it like this:
class UsernameField(forms.CharField): def to_python(self, value): value = super().to_python(value) return None if value is None else unicodedata.normalize('NFKC', value)
and allow the field null condition to be validated on the model
level.
If you find this fix reasonable I'd be happy to open a PR with the suggested change.
My project is using Django 2.2 but it's the same for 3.1.
Change History (3)
comment:1 by , 4 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:2 by , 4 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
comment:3 by , 4 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Hi, thanks for the report — nice and clear.
I'm going to close this as a duplicate of #31972. As per the docs on Custom users and the built-in auth forms you'll need to extend or customise the forms here. (Using `ModelAdmin.get_form()` I imagine.)