... 基本上我正在使用视图名称为 'django.contrib.admin.views.main.change_stage' 的 url reverse 函数获取网址。正如......" /> ... 基本上我正在使用视图名称为 'django.contrib.admin.views.main.change_stage' 的 url reverse 函数获取网址。正如......"> ... 基本上我正在使用视图名称为 'django.contrib.admin.views.main.change_stage' 的 url reverse 函数获取网址。正如......" />
ChatGPT解决这个技术问题 Extra ChatGPT

Getting Django admin url for an object

Before Django 1.0 there was an easy way to get the admin url of an object, and I had written a small filter that I'd use like this: <a href="{{ object|admin_url }}" .... > ... </a>

Basically I was using the url reverse function with the view name being 'django.contrib.admin.views.main.change_stage'

reverse( 'django.contrib.admin.views.main.change_stage', args=[app_label, model_name, object_id] )

to get the url.

As you might have guessed, I'm trying to update to the latest version of Django, and this is one of the obstacles I came across, that method for getting the admin url doesn't work anymore.

How can I do this in django 1.0? (or 1.1 for that matter, as I'm trying to update to the latest version in the svn).


b
blueyed

You can use the URL resolver directly in a template, there's no need to write your own filter. E.g.

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

{% url 'admin:polls_choice_change' choice.id %}

{% url 'admin:polls_choice_changelist' %}

Ref: Documentation


markmuetz - Is this in the official Django docs anywhere? (how to use admin reverse URLs in templates)? If not, it should be.
shacker - It's all in the docs... just not in one place. The "url" template tag is documented here. In the section "New in Django 1.1:" the docs say that namespaced URLs are fine, and points you to the section on URL namespaces. Sticking it all together lets you reference the admin application easily in templates. N.B I remember the docs being different when I wrote the reply.
Do you know how to get a link to the "list" of choices? Example: if "{% url admin:polls_choice_add %}" gives "/admin/polls/choice/add" what would be the equivalent that would give me "/admin/polls/choice"?
{% url admin:polls_choice_changelist %} returns the '/admin/polls/choice' url
Reversing an admin url is currently fully documented here https://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls
g
giantas
from django.core.urlresolvers import reverse
def url_to_edit_object(obj):
  url = reverse('admin:%s_%s_change' % (obj._meta.app_label,  obj._meta.model_name),  args=[obj.id] )
  return u'<a href="%s">Edit %s</a>' % (url,  obj.__unicode__())

This is similar to hansen_j's solution except that it uses url namespaces, admin: being the admin's default application namespace.


Thanks, it helps. One thing i would change: use args=[object.pk] instead of args=[object.id]. It covers more common case, when primary key field has another name than id.
Good answer. FYI anyone using a more recent django will need to change object._meta.module_name to object._meta.model_name
Big thank you from a django newbie. object._meta.app_label let me ultimately get the name for django's own authentication app. It's auth, for example reverse(admin:auth_user_change, args=[object.id]) to jump to the change user page
Be sure to change object to obj. This guy is over writing a reserved built in symbol.
d
djvg

I had a similar issue where I would try to call reverse('admin_index') and was constantly getting django.core.urlresolvers.NoReverseMatch errors.

Turns out I had the old format admin urls in my urls.py file.

I had this in my urlpatterns:

(r'^admin/(.*)', admin.site.root),

which gets the admin screens working but is the deprecated way of doing it. I needed to change it to this:

(r'^admin/', include(admin.site.urls) ),

Once I did that, all the goodness that was promised in the Reversing Admin URLs docs started working.


Awesome, this fixed another issue I was having with the get_urls() method of ModelAdmin not being called. Thanks!
This "answer" is not correct it just shows how to properly add the admin app to your app, which solved a different problem that the author had. The real answer to the actual question is below - from markmuetz
Also, you need to have registered admin interface for the model, otherwise the URL won't exist.
F
Flimm

Using template tag admin_urlname:

There's another way for the later versions (>=1.10), recommend by the Django documentation, using the template tag admin_urlname:

{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>

Where opts is something like mymodelinstance._meta or MyModelClass._meta

One gotcha is you can't access underscore attributes directly in Django templates (like {{ myinstance._meta }}) so you have to pass the opts object in from the view as template context.


A
Antony Hatchkins

Essentially the same as Mike Ramirez's answer, but simpler and closer in stylistics to django standard get_absolute_url method:

from django.urls import reverse

def get_admin_url(self):
    return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name),
                   args=[self.id])

A
Alex Koshelev

For pre 1.1 django it is simple (for default admin site instance):

reverse('admin_%s_%s_change' % (app_label, model_name), args=(object_id,))

With the new namespacing it's admin:%s_%s_change
h
hasen

I solved this by changing the expression to:

reverse( 'django-admin', args=["%s/%s/%s/" % (app_label, model_name, object_id)] )

This requires/assumes that the root url conf has a name for the "admin" url handler, mainly that name is "django-admin",

i.e. in the root url conf:

url(r'^admin/(.*)', admin.site.root, name='django-admin'),

It seems to be working, but I'm not sure of its cleanness.


This works for 1.0, but will not work for 1.1, which has a better solution: see Alex Koshelev's answer.
Actually I tried it and it didn't work, and he said it's for 1.0, no?
Syntax has changed in 1.1 with the introduction of url namespacing: docs.djangoproject.com/en/dev/topics/http/urls/…
D
DarwinSurvivor

If you are using 1.0, try making a custom templatetag that looks like this:

def adminpageurl(object, link=None):
    if link is None:
        link = object
    return "<a href=\"/admin/%s/%s/%d\">%s</a>" % (
        instance._meta.app_label,
        instance._meta.module_name,
        instance.id,
        link,
    )

then just use {% adminpageurl my_object %} in your template (don't forget to load the templatetag first)


I
Ian Cohen

Here's another option, using models:

Create a base model (or just add the admin_link method to a particular model)

class CommonModel(models.Model):
    def admin_link(self):
        if self.pk:
            return mark_safe(u'<a target="_blank" href="../../../%s/%s/%s/">%s</a>' % (self._meta.app_label,
                    self._meta.object_name.lower(), self.pk, self))
        else:
            return mark_safe(u'')
    class Meta:
        abstract = True

Inherit from that base model

   class User(CommonModel):
        username = models.CharField(max_length=765)
        password = models.CharField(max_length=192)

Use it in a template

{{ user.admin_link }}

Or view

user.admin_link()

I don't think this is a good solution. Building a URL with string formatting is a bad habit. Please use reverse().

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now