Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions rest_framework/authtoken/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ def url_for_result(self, result):

class TokenAdmin(admin.ModelAdmin):
list_display = ('key', 'user', 'created')
list_filter = ('created',)
fields = ('user',)
search_fields = ('user__username',)
search_fields = ('user__%s' % User.USERNAME_FIELD,)
search_help_text = _('Username')
ordering = ('-created',)
ordering = ('user__%s' % User.USERNAME_FIELD,)
Comment on lines +28 to +30
Copy link

Copilot AI Nov 26, 2025

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.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

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.

Copy link
Contributor Author

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.

actions = None # Actions not compatible with mapped IDs.

def get_changelist(self, request, **kwargs):
Expand Down
26 changes: 25 additions & 1 deletion tests/test_authtoken.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import importlib
from io import StringIO
from unittest.mock import patch

import pytest
from django.contrib.admin import site
Expand All @@ -11,7 +12,7 @@
from rest_framework.authtoken.admin import TokenAdmin
from rest_framework.authtoken.management.commands.drf_create_token import \
Command as AuthTokenCommand
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.models import Token, TokenProxy
from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.exceptions import ValidationError

Expand All @@ -36,6 +37,29 @@ def test_model_admin_displayed_fields(self):
token_admin = TokenAdmin(self.token, self.site)
assert token_admin.get_fields(mock_request) == ('user',)

@patch('django.contrib.admin.site.register') # avoid duplicate registrations
def test_model_admin__username_field(self, mock_register):
import rest_framework.authtoken.admin as authtoken_admin_m

class EmailUser(User):
USERNAME_FIELD = 'email'
username = None

for user_model in (User, EmailUser):
with (
self.subTest(user_model=user_model),
patch('django.contrib.auth.get_user_model', return_value=user_model) as get_user_model
):
importlib.reload(authtoken_admin_m) # reload after patching
assert get_user_model.call_count == 1

mock_request = object()
token_admin = authtoken_admin_m.TokenAdmin(TokenProxy, self.site)
assert token_admin.get_search_fields(mock_request) == (f'user__{user_model.USERNAME_FIELD}',)
assert token_admin.get_ordering(mock_request) == (f'user__{user_model.USERNAME_FIELD}',)

importlib.reload(authtoken_admin_m) # restore after testing

def test_token_string_representation(self):
assert str(self.token) == 'test token'

Expand Down