-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Update TokenAdmin to respect USERNAME_FIELD of the user model. #9836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
a0161c4 to
5ff42dc
Compare
5ff42dc to
941cc57
Compare
941cc57 to
fb633f4
Compare
| search_fields = ('user__username',) | ||
| search_fields = ('user__%s' % User.USERNAME_FIELD,) | ||
| search_help_text = _('Username') | ||
| ordering = ('-created',) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we should keep this ordering = ('-created',) ? what's your thoughts
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think default ordering by username combined with a creation date filter makes more sense for several reasons:
- You usually know which user's token you are looking for. So when you search for part of the username, it's easier to scan the search results if they are ordered by username.
- When you have a date in mind, it is usually in the recent past (which is covered by the options of the created filter).
- Manually ordering by created is always possible if desired.
createdis not indexed while the username field typically should be. So, if anyone deals with a lot of tokens, loading the page should be slower.
But no hard opinion on this. We can stick with -created ordering if you find that better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, created is not indexed while the username field typically should be
this make sense to me, and if this is the case then i don't have any problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. Marking as resolved.
Source reference for the fields:
# rest_framework/authtoken/models.py::Token
created = models.DateTimeField(_("Created"), auto_now_add=True)
# django/contrib/auth/models.py::AbstractUser
username = models.CharField(
_("username"),
max_length=150,
unique=True, # --> adds index
help_text=_(
"Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
),
validators=[username_validator],
error_messages={
"unique": _("A user with that username already exists."),
},
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I'm late to the party here, but one thing that comes to mind is how this will look in the UI. The ordering is by username but AFAIK the username isn't displayed on the page. If the email field is configured as username, the values could be quite different from the user display, making the ordering looks almost random.
Not sure if that's a big problem, though. And the point you raised about the lack of index is a good one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the email field is configured as username, the values could be quite different from the user display, making the ordering looks almost random.
Yes that sorting might create confusion in user mind. This will be surprise for the users.
if there is a performance problem then they can override the indexing and if require we can create seperate PR for adding index on created_at field if we have strong use case in future ( my opinion).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@browniebroke The user is displayed. Here is a reference screenshot after the changes.
Apart from the indexing issue, I would prefer ordering by username because if you do a partial match search (e.g. adam in the screenshot), it is easier to scan through the result list if it is ordered by username.
OTOH, if tokens are long-lived, the creation date soon becomes irrelevant: Created at Sept. 2022 vs Oct. 2022 is pretty much the same thing in 2025.
But I think we have already spent more energy on this than its worth. Let me know of your final decision on ordering and I'll roll with it.
I can also follow-up with adding indexing to created_at, if you feel this is needed. Anecdotally, for the ~500 tokens in our app, the admin loading difference is not noticeable. But I don't know how many tokens other apps may have.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I see, the default __str__ for the user uses username:
I can see some apps where it might be customised as first_name last_name but that's perhaps fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR updates the TokenAdmin class to properly support custom user models with different username fields. Django allows projects to customize the username field via USERNAME_FIELD, and the admin interface previously hardcoded 'username' instead of respecting this setting.
Key changes:
- Updated
search_fieldsandorderingto dynamically useUser.USERNAME_FIELDinstead of hardcoded 'username' - Added
list_filterfor the 'created' field - Changed default ordering from descending creation date to ascending username field
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| search_fields = ('user__%s' % User.USERNAME_FIELD,) | ||
| search_help_text = _('Username') | ||
| ordering = ('-created',) | ||
| ordering = ('user__%s' % User.USERNAME_FIELD,) |
Copilot
AI
Nov 26, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The changes to use USERNAME_FIELD instead of hardcoded 'username' lack test coverage. Consider adding tests that verify the admin configuration works correctly with a custom user model that uses a different USERNAME_FIELD (e.g., 'email'), ensuring search and ordering function as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@m000 it would be great to add test coverage for the changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added. It took a while to figure it out. Admin tests are a major PITA because modules include code that runs on load.
fb633f4 to
dd3e82d
Compare
p-r-a-v-i-n
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for adding test coverage.
Admin tests are a major PITA because modules include code that runs on load.
😄 I'm happy you did it. Nice work :) . well this part of test and code also new for me.
other than this everything looks good to me , I think the precommit hook is failing fix it and lets wait for Bruno and Auvi for feedback.
dd3e82d to
d78b161
Compare
- Respect USERNAME_FIELD of the user model. - Default ordering by username. - Filter by creation date.
Thanks for the hint. I had missed the existence of the pre-commit hooks. I had chomped an extra line and isort complained. It should be good now. |
d78b161 to
77be42e
Compare
Description
TokenAdmin assumed a fixed username field for the model specified by
settings.AUTH_USER_MODEL. However, django allows using some other field as the username, and this is specified by overriding theUSERNAME_FIELDproperty. See [1].Also, switched default ordering to also use the username, and added filter for creation date.
[1] https://docs.djangoproject.com/en/5.2/topics/auth/customizing/#django.contrib.auth.models.CustomUser.USERNAME_FIELD