5

As described this answer, we can use the url tag to reverse Django admin URLs. However, in the examples shown there, you need the app name and model name in the string passed to url. Is there a way to pass those in as parameters instead? What I'm looking to do is something like this:

{% url 'something here' app_name model_name object_id %}

What do I put for 'something here'?

Community
  • 1
  • 1
Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268
  • 1
    I suggest you install `django_extensions` and use its command to find URL names. `python manage.py show_urls` – rabbit.aaron Jun 22 '19 at 16:49
  • @rabbit.aaron You should post that as an answer. Also, it will help to show an example to illustrate how that tool will answer my question. – Code-Apprentice Jun 23 '19 at 19:21

2 Answers2

22

I suggest using django_extensions to use its show_urls command to find url names.

simply do

pip install django_extensions

then add django_extensions to your INSTALLED_APPS

#settings.py
INSTALLED_APPS = [
    #...
    'django_extensions',
]

Then you can run

python manage.py show_urls

You can use it with grep to filter out the relevant URLs you need. e.g.

python manage.py show_urls | grep password
/admin/auth/user/<id>/password/  django.contrib.auth.admin.user_change_password  admin:auth_user_password_change
/admin/password_change/  django.contrib.admin.sites.password_change      admin:password_change
/admin/password_change/done/     django.contrib.admin.sites.password_change_done admin:password_change_done

And say we want to use django.contrib.auth.admin.user_change_password in our template:

We can do:

{% url "admin:auth_user_password_change" user.pk %}

P.S. You don't really need django_extensions for your production environment, so you probably want to install it locally for development use only.


Resources:

django_extensions installation documentation django_extensions commands

Community
  • 1
  • 1
rabbit.aaron
  • 2,369
  • 16
  • 25
  • Question: is the middle column the name of the function that is registered for that view? If so, can I use this name with the `url` tag or `reverse()`? – Code-Apprentice Jun 24 '19 at 15:51
  • yes you can use the names with `reverse`. the colon specifies a namespace, look here: https://docs.djangoproject.com/en/2.2/topics/http/urls/#url-namespaces – rabbit.aaron Jun 25 '19 at 00:07
  • I'm referring to the names **in the middle "column"** such as `django.contrib.auth.admin.user_change_password`. (I don't see any colon here.) – Code-Apprentice Jun 25 '19 at 15:02
  • For example, when I run `./manage.py show_urls`, I see a path such as `/my_app/my_model//change/ django.contrib.admin.options.change_view admin:myapp_mymodel_change`. To reverse the `admin:myapp_mymodel_change` route, I have to hard code both the name of the app and the name of the model. My question is if there is a way to pass both of these as parameters to `reverse()` (or `{% url %}`). From what I can tell there isn't. Of course, I can easily build my own function with some string formatting. – Code-Apprentice Jun 25 '19 at 15:07
  • 1
    I don't think Django provide such feature. If you take a look at `django.contrib.admin.options.ModelAdmin.get_urls`. You'll see how the URLs are generated. – rabbit.aaron Jun 25 '19 at 23:37
3

If you want to reverse admin urls, the default admin.sites.urls has a urlpattern in it that looks like:

urlpatterns = [
        path('', wrap(self.index), name='index'),
        path('login/', self.login, name='login'),
        path('logout/', wrap(self.logout), name='logout'),
        path('password_change/', wrap(self.password_change, cacheable=True), name='password_change'),
        path(
            'password_change/done/',
            wrap(self.password_change_done, cacheable=True),
            name='password_change_done',
        ),
        path('jsi18n/', wrap(self.i18n_javascript, cacheable=True), name='jsi18n'),
        path(
            'r/<int:content_type_id>/<path:object_id>/',
            wrap(contenttype_views.shortcut),
            name='view_on_site',
        ),
    ]

Looking at the above code you can simply use {% url 'admin:index' %} in templete of reverse('admin:index') else where for the admin dashboard url. Likewise same with all other admin urls patterns

salafi
  • 387
  • 6
  • 9
  • Thank you for the info. My original question was about the admin routes to a specific model in an app, such as the changeform view. The question I linked to shows examples with the app and model name included in the route name. However, I have a situation where I'd like to pass those as parameters instead. My question is asking how to do that. – Code-Apprentice Dec 17 '19 at 17:25