Reputation: 2127
In my django app, I've created a custom User model which extends AbstractUser
. I updated the AUTH_USER_MODEL
and registered it under the admin like so
admin.site.register(MyUser, UserAdmin)
I ran the migrations and then went under my admin page and saw it listed under the app's models. But when I tried created a new user from that page, it gave me this error.
User class in models.py:
class MyUser(AbstractUser):
id = models.CharField(primary_key = True, unique = True, max_length = 50)
Any ideas? Edit: updated to include main urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^api/', include('api.urls'))
]
Edit 2: updated to include stacktrace
Internal Server Error: /admin/api/myuser/add/
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 551, in wrapper
return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/decorators/cache.py", line 57, in _wrapped_view_func
response = view_func(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/sites.py", line 224, in inner
return view(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper
return bound_func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/views/decorators/debug.py", line 76, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper
return bound_func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 103, in add_view
return self._add_view(request, form_url, extra_context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 131, in _add_view
extra_context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1508, in add_view
return self.changeform_view(request, None, form_url, extra_context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 67, in _wrapper
return bound_func(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 149, in _wrapped_view
response = view_func(request, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/decorators.py", line 63, in bound_func
return func.__get__(self, type(self))(*args2, **kwargs2)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1408, in changeform_view
return self._changeform_view(request, object_id, form_url, extra_context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1453, in _changeform_view
return self.response_add(request, new_object)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/admin.py", line 211, in response_add
post_url_continue)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/admin/options.py", line 1052, in response_add
current_app=self.admin_site.name,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/urls/base.py", line 91, in reverse
return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/urls/resolvers.py", line 497, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'api_myuser_change' with arguments '('',)' not found. 1 pattern(s) tried: ['admin/api/myuser/(.+)/change/$']
Edit 3: INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework.authtoken',
'api',
'django_jinja',
]
Upvotes: 3
Views: 1646
Reputation: 1
after a long search and struggle, I found this solution really it's working for me. its enables me to add edit API user from admin UI with my customizations.
you just need to add this code into your app's admin.py file and only replace your custom model name with your model then it's working fine.
import typing
from django.contrib import admin, messages
from django.db import models
from django.http.request import HttpRequest
from your_app.models import your_custom_model
from rest_framework_api_key.models import AbstractAPIKey
class APIKeyModelAdmin(admin.ModelAdmin):
model: typing.Type[AbstractAPIKey]
list_display = (
"prefix",
"name",
"created",
"_has_expired",
"revoked",
)
list_filter = ("created",)
search_fields = ("name", "prefix", "client_id")
def get_readonly_fields(
self, request: HttpRequest, obj: models.Model = None
) -> typing.Tuple[str, ...]:
obj = typing.cast(AbstractAPIKey, obj)
fields: typing.Tuple[str, ...]
fields = ("prefix",)
if obj is not None and obj.revoked:
fields = fields + ("name", "revoked", "expiry_date")
return fields
def save_model(
self,
request: HttpRequest,
obj: AbstractAPIKey,
form: typing.Any = None,
change: bool = False,
) -> None:
created = not obj.pk
if created:
key = self.model.objects.assign_key(obj)
obj.save()
message = (
"The API key for {} is: {}. ".format(obj.name, key)
+ "Please store it somewhere safe: "
+ "you will not be able to see it again."
)
messages.add_message(request, messages.WARNING, message)
else:
obj.save()
admin.site.register(your_custom_model, APIKeyModelAdmin)
Upvotes: 0
Reputation: 405
The error message shows the url as /myuser/add
and your urls say it only have the /myuser/change/
defined. Define the /myuser/add
class/function view or update the url to point to the add class/function view.
Upvotes: 0
Reputation:
you'd have register your model in admin site
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User
admin.site.register(User, UserAdmin)
also you must have your model with id with integer number
class MyUser(AbstractUser):
pass
Upvotes: 0
Reputation: 678
You've replaced your primary key with a CharField but you're still using Django's UserAdmin ModelAdmin. Django's UserAdmin doesn't ask for the ID – it's defaulting to an empty string. (You can verify this by checking for the empty string in the arguments from the NoReverseMatch Exception.)
You need to create a ModelAdmin that allows you to specify the ID so it doesn't end up as an empty string. The following admin.py
will allow you to specify the ID thus getting rid of your NoReverseMatch exception.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import MyUser
class MyUserAdmin(UserAdmin):
add_fieldsets = (
(None, {
'fields': ('id', 'username', 'password1', 'password2'),
}),
)
# Register your models here.
admin.site.register(MyUser, MyUserAdmin)
Upvotes: 6