I have a customized admin view - my app is called virtual
:
class VirtualAdminSite(admin.AdminSite):
index_template = "virtual/admin_index.html"
def index(self, request, extra_context=None):
extra_context = extra_context or {}
return super().index(request, extra_context)
def get_urls(self):
urls = super().get_urls()
my_urls = path("virtual/info/", self.admin_view(self.info), name="info")
urls.append(my_urls)
return urls
def info(self, request):
return HttpResponse("hello")
and I want to be able to include the url in the newly created admin_index.html
, so I did
(please ignore I used HTMX to load this bc it's shorter than AJAX in vanilla JS):
{% block content %}
<div id="content-main">
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
Info: <h3 hx-get="{% url 'info' %}" hx-trigger="load"> loading ... </h3>
</div>
{% endblock %}
but I get a: Reverse for 'info' not found. 'info' is not a valid view function or pattern name
error.
I already tried adding admin/
in the path, and deleting virtual
but everything fails.
edit: When looping over all the urls before returning them:
<URLPattern '' [name='index']>
<URLPattern 'login/' [name='login']>
<URLPattern 'logout/' [name='logout']>
<URLPattern 'password_change/' [name='password_change']>
<URLPattern 'password_change/done/' [name='password_change_done']>
<URLPattern 'autocomplete/' [name='autocomplete']>
<URLPattern 'jsi18n/' [name='jsi18n']>
<URLPattern 'r/<int:content_type_id>/<path:object_id>/' [name='view_on_site']>
<URLResolver <URLPattern list> (None:None) 'virtual/product/'>
<URLResolver <URLPattern list> (None:None) 'virtual/store/'>
<URLPattern '^(?P<app_label>virtual)/$' [name='app_list']>
<URLPattern '(?P<url>.*)$'>
<URLPattern 'virtual/info/' [name='info']>
I see nothing too odd. Still I see a 404 in the network tab when trying to resolve: {% url 'admin:info' %}
.
If I recall correctly, the .urls
of a site by default pases the url patterns as well as the app_namespace
which is by default admin
, and the instancce namespace, which is the name of the site you attached. Indeed, in the source codeĀ [GitHub], we see:
@property def urls(self): return self.get_urls(), "admin", self.name
You thus refer to the view with:
{% url 'admin:info' %}
Additionally, you need to provide a name for the path:
my_urls = path('virtual/info/', self.admin_view(self.info), name='info')
A final problem turned out to be that you added the path at the end of the list, and there is a "catch all" pattern before that, so you can insert it in front, or at least before the "catch all":
def get_urls(self):
urls = super().get_urls()
my_urls = path('virtual/info/', self.admin_view(self.info), name='info')
urls.insert(0, my_urls)
return urls