如何使用 django 管理面板中的自定义管理字段重定向到自定义管理页面

时间:2021-02-03 17:30:51

标签: django django-admin custom-pages

有我的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 %} &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.

如何解决此问题以重定向到名称为 advanced_config 的 url?

自定义网址工作正常。

1 个答案:

答案 0 :(得分:0)

有问题的部分在 reverse() 结构中。

最后重定向按预期进行:

return mark_safe('<a class="custom" href="%s">Advanced Config Page</a>' % reverse("admin:advanced_config",  kwargs={ "plug_id": obj.pk }))

P.S : get_urls() 函数中定义的 url 的命名空间是 admin