#django #django-admin #custom-pages
#django #django-admin #пользовательские страницы
Вопрос:
Наличие моего PlugAdmin
класса
class PlugAdmin(admin.ModelAdmin):
list_display = (...'custom_link')
admin.py
среди других полей моей модели я определил custom_link
поле, как показано ниже:
def custom_link(self, obj):
info = (obj._meta.app_label, obj._meta.model_name)
return mark_safe('<a class="custom" href="%s">Advanced Config Page</a>' % reverse('admin:%s/%s/advanced-config' % info, args=(obj.pk,)))
Нажав кнопку custom_link
«Моя цель — перенаправить на advanced_config_view
пользовательскую страницу администратора, которая была определена правильно (как в admin.site.urls, так и в виде представления:
def get_urls(self):
urls = super().get_urls()
my_urls = [
path('<uuid:plug_id>/advanced-config/', self.admin_site.admin_view(self.advanced_config_view), name = "advanced_config"),
]
return my_urls urls
def advanced_config_view(self, request, plug_id):
plug = Plug.objects.get(id = plug_id)
context = dict(
# Include common variables for rendering the admin template.
self.admin_site.each_context(request),
plug = plug,
)
return TemplateResponse(request, "custom_admin/advanced_config.html", context)
Моя страница не может загрузиться, и я получил сообщение об ошибке от Traceback :
Template error:
In template /home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templates/admin/base.html, error at line 65
Reverse for 'stations/plug/advanced-config' not found. 'stations/plug/advanced-config' is not a valid view function or pattern name.
55 : <a href="{% url 'admin:logout' %}">{% translate 'Log out' %}</a>
56 : {% endblock %}
57 : </div>
58 : {% endif %}
59 : {% endblock %}
60 : {% block nav-global %}{% endblock %}
61 : </div>
62 : <!-- END Header -->
63 : {% block breadcrumbs %}
64 : <div class="breadcrumbs">
65 : <a href="{% url 'admin:inde x' %}">{% translate 'Home' %}</a>
66 : {% if title %} amp;rsaquo; {{ title }}{% endif %}
67 : </div>
68 : {% endblock %}
69 : {% endif %}
70 :
71 : <div class="main shifted" id="main">
72 : {% if not is_popup and is_nav_sidebar_enabled %}
73 : {% block nav-sidebar %}
74 : {% include "admin/nav_sidebar.html" %}
75 : {% endblock %}
Traceback (most recent call last):
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/db/models/options.py", line 575, in get_field
return self.fields_map[field_name]
During handling of the above exception ('custom_link'), another exception occurred:
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/utils.py", line 264, in lookup_field
f = _get_non_gfk_field(opts, name)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/utils.py", line 295, in _get_non_gfk_field
field = opts.get_field(name)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/db/models/options.py", line 577, in get_field
raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
During handling of the above exception (Plug has no field named 'custom_link'), another exception occurred:
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/asgiref/sync.py", line 330, in thread_handler
raise exc_info[1]
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/core/handlers/exception.py", line 38, in inner
response = await get_response(request)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/core/handlers/base.py", line 261, in _get_response_async
response = await sync_to_async(response.render, thread_sensitive=True)()
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/asgiref/sync.py", line 296, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "/usr/lib/python3.7/asyncio/tasks.py", line 414, in wait_for
return await fut
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/asgiref/sync.py", line 334, in thread_handler
return func(*args, **kwargs)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/response.py", line 105, in render
self.content = self.rendered_content
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/response.py", line 83, in rendered_content
return template.render(context, self._request)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/backends/django.py", line 61, in render
return self.template.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 170, in render
return self._render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/loader_tags.py", line 150, in render
return compiled_parent._render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 162, in _render
return self.nodelist.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/loader_tags.py", line 62, in render
result = block.nodelist.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 938, in render
bit = node.render_annotated(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/base.py", line 905, in render_annotated
return self.render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templatetags/base.py", line 33, in render
return super().render(context)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/template/library.py", line 214, in render
_dict = self.func(*resolved_args, **resolved_kwargs)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templatetags/admin_list.py", line 341, in result_list
'results': list(results(cl)),
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templatetags/admin_list.py", line 317, in results
yield ResultList(None, items_for_result(cl, res, None))
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templatetags/admin_list.py", line 308, in __init__
super().__init__(*items)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/templatetags/admin_list.py", line 233, in items_for_result
f, attr, value = lookup_field(field_name, result, cl.model_admin)
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/contrib/admin/utils.py", line 273, in lookup_field
value = attr(obj)
File "/home/giorgos/Desktop/ev-loader/backend/stations/admin.py", line 87, in custom_link
return mark_safe('<a class="custom" href="%s">Advanced Config Page</a>' % reverse('admin:%s/%s/advanced-config' % info, args=(obj.pk,)))
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/urls/base.py", line 87, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/urls/resolvers.py", line 685, in _reverse_with_prefix
raise NoReverseMatch(msg)
Exception Type: NoReverseMatch at /admin/stations/plug/
Exception Value: Reverse for 'stations/plug/advanced-config' not found. 'stations/plug/advanced-config' is not a valid view function or pattern name.
Как я могу исправить это, чтобы перенаправить на URL с именем advanced_config?
Пользовательский URL работает правильно.
Ответ №1:
Неисправная часть была в reverse()
конструкции.
Наконец, перенаправление происходит, как и ожидалось, с :
return mark_safe('<a class="custom" href="%s">Advanced Config Page</a>' % reverse("admin:advanced_config", kwargs={ "plug_id": obj.pk }))
P.S: Пространство имен URL-адресов, определенных в get_urls()
функции, — admin