RobMcC
RobMcC

Reputation: 412

Django/wagtail admin page links pointing to invalid address

I have a wagtail site and have a problem with the ‘users’ section of the admin page

My users/admin.py is :

from django.contrib import admin
from django.contrib.auth import admin as auth_admin
from django.contrib.auth import get_user_model

from psymatik.users.forms import (
    UserChangeForm,
    UserCreationForm,
)

User = get_user_model()

admin.site.register(User)

class UserAdmin(auth_admin.UserAdmin):
    form = UserChangeForm
    add_form = UserCreationForm
    fieldsets = (
        ("User", {"fields": ("username",)}),
    ) + auth_admin.UserAdmin.fieldsets
    list_display = ["username", "is_superuser"]
    search_fields = ["username"]

And my users/wagtail_hooks.py is:

from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register 

from .models import User


class UserAdmin(ModelAdmin):
    model = User 
    menu_label = "Users"  
    menu_icon = "pick" 
    menu_order = 200 
    add_to_settings_menu = False 
    exclude_from_explorer = False 
    list_display = ( "name")
    list_filter = ("name")
    search_fields = ("name")
modeladmin_register(UserAdmin)

The issues I have is that when I am at admin/users and I click on the Users link in the sidebar I am taken to admin/users/user and get the error

“ValueError at /admin/users/user/ Field 'id' expected a number but got 'user’.”

Why is the sidebar link pointing to admin/users/user rather than just admin/users (which does work)? What is the best way to set this up?

Upvotes: 0

Views: 634

Answers (1)

gasman
gasman

Reputation: 25317

When you register a model with ModelAdmin, the URLs will be formed from the app name ('users' here) and the model name ('user'), so /admin/users/user is expected. However, in this case Wagtail already provides a user management area (available from the Settings submenu) that exists under the /admin/users/ URL namespace - these URLs end up colliding with the ones you add through ModelAdmin.

It looks like your UserAdmin definition is more or less duplicating the functionality already provided by Wagtail, so you may not need this at all. If you do, one thing that might work is editing the INSTALLED_APPS setting in your project's settings to move your users app above wagtail.contrib.users - that way, the URL patterns for your own app will take precedence over Wagtail's built in /admin/users/ area, and it will correctly interpret anything under /admin/users/user/ as belonging to your own app (while letting all other URLs under /admin/users/ fall back to the Wagtail built-in area).

If that doesn't work, you'd need to either rename your users app (easier said than done for an established project...) or customise the ModelAdmin setup to use an alternative URL path. It doesn't look like ModelAdmin currently provides an official mechanism to do that, but overriding the AdminURLHelper object ought to work - within users/wagtail_hooks.py:

from wagtail.contrib.modeladmin.helpers import AdminURLHelper

class UsersAdminURLHelper(AdminURLHelper):
    def _get_action_url_pattern(self, action):
        # hard-code 'user-accounts' as the URL path instead of /users/user/
        if action == "index":
            return r"^user-accounts/$"
        return r"^user-accounts/%s/$" % action

class UserAdmin(ModelAdmin):
    model = User
    url_helper_class = UsersAdminURLHelper
    # all other settings as before

Incidentally, users/admin.py is unrelated here - it controls the Django admin backend, which is distinct from the Wagtail admin.

Upvotes: 1

Related Questions