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

问题描述

有我的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 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",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,)))
  File "/home/giorgos/.local/share/virtualenvs/backend-tSqKtrJ_/lib/python3.7/site-packages/django/urls/base.py",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?

自定义网址工作正常。

解决方法

有问题的部分在 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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...