Adjusted token admin to map to user ID. (#7341)

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.
This commit is contained in:
Carlton Gibson 2020-06-15 12:43:09 +02:00 committed by GitHub
parent b677b7b15d
commit e2bd3b6a57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 2 deletions

View File

@ -1,10 +1,51 @@
from django.contrib import admin
from django.contrib.admin.utils import quote
from django.contrib.admin.views.main import ChangeList
from django.contrib.auth import get_user_model
from django.core.exceptions import ValidationError
from django.urls import reverse
from rest_framework.authtoken.models import Token
from rest_framework.authtoken.models import Token, TokenProxy
User = get_user_model()
class TokenChangeList(ChangeList):
"""Map to matching User id"""
def url_for_result(self, result):
pk = result.user.pk
return reverse('admin:%s_%s_change' % (self.opts.app_label,
self.opts.model_name),
args=(quote(pk),),
current_app=self.model_admin.admin_site.name)
@admin.register(Token)
class TokenAdmin(admin.ModelAdmin):
list_display = ('key', 'user', 'created')
fields = ('user',)
ordering = ('-created',)
actions = None # Actions not compatible with mapped IDs.
def get_changelist(self, request, **kwargs):
return TokenChangeList
def get_object(self, request, object_id, from_field=None):
"""
Map from User ID to matching Token.
"""
queryset = self.get_queryset(request)
field = User._meta.pk
try:
object_id = field.to_python(object_id)
user = User.objects.get(**{field.name: object_id})
return queryset.get(user=user)
except (queryset.model.DoesNotExist, User.DoesNotExist, ValidationError, ValueError):
return None
def delete_model(self, request, obj):
# Map back to actual Token, since delete() uses pk.
token = Token.objects.get(key=obj.key)
return super().delete_model(request, token)
admin.site.register(TokenProxy, TokenAdmin)

View File

@ -37,3 +37,16 @@ class Token(models.Model):
def __str__(self):
return self.key
class TokenProxy(Token):
"""
Proxy mapping pk to user pk for use in admin.
"""
@property
def pk(self):
return self.user.pk
class Meta:
proxy = True
verbose_name = "token"