Skip to content

Commit ce0ba1e

Browse files
committed
Adjusted token admin to map to user ID.
Closes #6131. * Adds a proxy model for Token that uses the user.pk, rather than it's own. * Adjusts Admin to map back from User ID to token instance.
1 parent 65add66 commit ce0ba1e

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

rest_framework/authtoken/admin.py

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,56 @@
1+
from django.core.exceptions import ValidationError
12
from django.contrib import admin
3+
from django.contrib.admin.utils import quote
4+
from django.contrib.admin.views.main import ChangeList
5+
from django.contrib.auth import get_user_model
6+
from django.urls import reverse
27

3-
from rest_framework.authtoken.models import Token
8+
from rest_framework.authtoken.models import TokenProxy, Token
9+
10+
11+
User = get_user_model()
12+
13+
14+
class TokenChangeList(ChangeList):
15+
"""Map to matching User id"""
16+
def url_for_result(self, result):
17+
pk = result.user.pk
18+
return reverse('admin:%s_%s_change' % (self.opts.app_label,
19+
self.opts.model_name),
20+
args=(quote(pk),),
21+
current_app=self.model_admin.admin_site.name)
422

523

6-
@admin.register(Token)
724
class TokenAdmin(admin.ModelAdmin):
825
list_display = ('key', 'user', 'created')
926
fields = ('user',)
1027
ordering = ('-created',)
28+
actions = None # Actions not compatible with mapped IDs.
29+
30+
def get_changelist(self, request, **kwargs):
31+
return TokenChangeList
32+
33+
def get_object(self, request, object_id, from_field=None):
34+
"""
35+
Return an instance matching the field and value provided, the primary
36+
key is used if no field is provided. Return ``None`` if no match is
37+
found or the object_id fails validation.
38+
"""
39+
queryset = self.get_queryset(request)
40+
model = queryset.model
41+
field = User._meta.pk
42+
try:
43+
object_id = field.to_python(object_id)
44+
print(object_id)
45+
user = User.objects.get(**{field.name: object_id})
46+
return queryset.get(user=user)
47+
except (model.DoesNotExist, User.DoesNotExist, ValidationError, ValueError):
48+
return None
49+
50+
def delete_model(self, request, obj):
51+
# Map back to Token, since delete() uses pk.
52+
token = Token.objects.get(key=obj.key)
53+
return super().delete_model(request, token)
54+
55+
56+
admin.site.register(TokenProxy, TokenAdmin)

rest_framework/authtoken/models.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,16 @@ def generate_key(self):
3737

3838
def __str__(self):
3939
return self.key
40+
41+
42+
class TokenProxy(Token):
43+
"""
44+
Proxy mapping pk to user pk for use in admin.
45+
"""
46+
@property
47+
def pk(self):
48+
return self.user.pk
49+
50+
class Meta:
51+
proxy = True
52+
verbose_name = "token"

0 commit comments

Comments
 (0)