Issue
I'm trying to do default admin site just like this
here is settings.INSTALLED_APPS
INSTALLED_APPS = [
#'django.contrib.admin',
'core.apps.AppAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'routefilterfeeder.apps.RoutefilterfeederConfig',
]
here is my core.apps
from django.contrib.admin.apps import AdminConfig
class AppAdminConfig(AdminConfig):
default_site = 'core.admin.AppAdminSite'
and here is my core.admin
from django.contrib.admin import AdminSite
#from django.utils.translation import ugettext_lazy as _
from django.contrib import admin
from django.apps import apps
from django.contrib.admin.sites import site
from operator import itemgetter
# ref: https://unfoldadmin.com/blog/custom-django-admin-site/
class AppAdminSite(AdminSite):
def index(self, request, extra_context=None):
# Update extra_context with new variables
return super().index(request, extra_context)
def get_app_list(self, request, app_label=None):
"""
Return a sorted list of all the installed apps that have been
registered in this site.
"""
app_dict = self._build_app_dict(request, app_label)
# First, sort the models of each app, based on 'admin_priority'
# Ref: https://forum.djangoproject.com/t/reordering-list-of-models-in-django-admin/5300
for app_name in app_dict.keys():
app = app_dict[app_name]
model_priority = {
model['object_name']: getattr(
site._registry[apps.get_model(app_name, model['object_name'])],
'admin_site_priority',
9999
)
for model in app['models']
}
app['models'].sort(key=lambda x: model_priority[x['object_name']])
yield app
# Sort the apps alphabetically.
all_app = sorted(app_dict.values(), key=lambda x: x["name"].lower())
app_list = []
prio_list = []
# Sort the models alphabetically within each app.
for app in all_app:
this_config = apps.get_app_config(app["app_label"])
try :
this_prio = this_config.admin_site_priority
prio_list.append([this_prio,app['app_label']])
except Exception as e:
app_list.append(app)
prio_list = sorted(prio_list, key=itemgetter(0))
for p in prio_list:
this_app = [a for a in all_app if a['app_label']== p[1]][0]
app_list.append(this_app)
return app_list
class MyModelAdmin(admin.ModelAdmin):
admin_site_priority = 9999
Currently have only one app, with config like
from django.apps import AppConfig
class RoutefilterfeederConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'routefilterfeeder'
admin_site_priority = 1
I can login to this django site. When I click one model (i.e: Feeders) Under 'routefilterfeeder' the main area show Feeder list display .... no problem.
the nav part display navigation menu 'Home › Routefilterfeeder › Feeders'
But when I click 'Routefilterfeeder' from that nav menu, I got error 'generator' object is not subscriptable', with traceback:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/routefilterfeeder/
Django Version: 5.0
Python Version: 3.10.12
Installed Applications:
['core.apps.AppAdminConfig',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'routefilterfeeder.apps.RoutefilterfeederConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/contrib/admin/sites.py", line 259, in wrapper
return self.admin_view(view, cacheable)(*args, **kwargs)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/utils/decorators.py", line 188, in _view_wrapper
result = _process_exception(request, e)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/utils/decorators.py", line 186, in _view_wrapper
response = view_func(request, *args, **kwargs)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
response = view_func(request, *args, **kwargs)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/contrib/admin/sites.py", line 240, in inner
return view(request, *args, **kwargs)
File "/home/bino/Documents/pjxadmin/venv/lib/python3.10/site-packages/django/contrib/admin/sites.py", line 577, in app_index
"title": _("%(app)s administration") % {"app": app_list[0]["name"]},
Exception Type: TypeError at /admin/routefilterfeeder/
Exception Value: 'generator' object is not subscriptable
Kindly please tell me how to fix this.
Solution
The problem is you are returning a generator with the keyword yield
in your get_app_list
:
app['models'].sort(key=lambda x: model_priority[x['object_name']])
yield app
You state in your docstring:
Return a sorted list of all the installed apps that have been registered in this site.
but by yielding you return a generator object. This object can be iterated over but otherwise does not behave like a list.
To prevent your error you need to return the full list of apps here and not just yielding one app.
Answered By - Martin Achenrainer
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.