aidnani8
aidnani8

Reputation: 2127

NoReverseMatch error when creating new users through admin

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.

enter image description here

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

Answers (4)

Aman
Aman

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

marchWest
marchWest

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

user5975488
user5975488

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

Matt Hardcastle
Matt Hardcastle

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

Related Questions