问题描述
有我的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 %} › {{ 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