Lấy url quản trị Django cho một đối tượng


168

Trước Django 1.0, có một cách dễ dàng để lấy url quản trị của một đối tượng và tôi đã viết một bộ lọc nhỏ mà tôi sử dụng như thế này: <a href="{{ object|admin_url }}" .... > ... </a>

Về cơ bản tôi đã sử dụng chức năng đảo ngược url với tên xem là 'django.contrib.admin.views.main.change_stage'

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

để lấy url

Như bạn có thể đoán, tôi đang cố cập nhật lên phiên bản Django mới nhất và đây là một trong những trở ngại tôi gặp phải, phương pháp lấy url quản trị viên không còn hoạt động nữa.

Làm thế nào tôi có thể làm điều này trong django 1.0? (hoặc 1.1 cho vấn đề đó, vì tôi đang cố cập nhật lên phiên bản mới nhất trong svn).

Câu trả lời:


61

Tôi gặp vấn đề tương tự khi tôi cố gắng gọi reverse('admin_index')và liên tục gặp django.core.urlresolvers.NoReverseMatchlỗi.

Hóa ra tôi có các url quản trị định dạng cũ trong tệp urls.py của tôi.

Tôi đã có cái này trong urlpotypes của tôi:

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

làm cho màn hình quản trị hoạt động nhưng là cách làm không được chấp nhận. Tôi cần phải thay đổi nó thành thế này:

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

Khi tôi đã làm điều đó, tất cả những điều tốt đẹp đã được hứa hẹn trong các tài liệu URL quản trị đảo ngược bắt đầu hoạt động.


Thật tuyệt vời, điều này đã khắc phục một sự cố khác mà tôi gặp phải với phương thức get_urls () của ModelAdmin không được gọi. Cảm ơn!
Arnaud

8
url tốt nhất cho vấn đề này: docs.djangoproject.com/en/dev/ref/contrib/admin/ mẹo
Dingo

4
"Câu trả lời" này không chính xác, nó chỉ cho thấy cách thêm đúng ứng dụng quản trị viên vào ứng dụng của bạn, điều này đã giải quyết một vấn đề khác mà tác giả gặp phải. Câu trả lời thực sự cho câu hỏi thực tế nằm bên dưới - từ markmuetz
Declan Shanaghy

Ngoài ra, bạn cần phải có giao diện quản trị viên đã đăng ký cho mô hình, nếu không URL sẽ không tồn tại.
Flimm

412

Bạn có thể sử dụng trình phân giải URL trực tiếp trong một mẫu, không cần phải viết bộ lọc của riêng bạn. Ví dụ

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Tham chiếu: Tài liệu


1
markmuetz - Đây có phải là tài liệu chính thức của Django ở bất cứ đâu không? (làm thế nào để sử dụng URL đảo ngược của quản trị viên trong các mẫu)? Nếu không, nó nên được.
Shacker

7
shacker - Đó là tất cả trong các tài liệu ... chỉ không ở một nơi. Thẻ mẫu "url" được ghi lại ở đây . Trong phần "Mới trong Django 1.1:" các tài liệu nói rằng các URL được đặt tên đều ổn và đưa bạn đến phần trên các không gian tên URL . Kết hợp tất cả lại với nhau cho phép bạn tham chiếu ứng dụng quản trị viên một cách dễ dàng trong các mẫu. NB Tôi nhớ các tài liệu là khác nhau khi tôi viết trả lời.
markmuetz

3
Bạn có biết làm thế nào để có được một liên kết đến "danh sách" các lựa chọn? Ví dụ: nếu "{% url admin: polls_choice_add%}" đưa ra "/ admin / polls / sự lựa chọn / thêm" điều gì sẽ tương đương với tôi "/ admin / polls / sự lựa chọn"?
DarwinSurvivor

2
{% url admin: polls_choice_changelist%} trả về url '/ admin / polls / sự lựa chọn'
luc

35
Việc đảo ngược một url quản trị hiện được ghi lại đầy đủ tại đây https://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls
Josh Russo

101
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__())

Điều này tương tự như giải pháp của hansen_j ngoại trừ việc nó sử dụng không gian tên url , admin: là không gian tên ứng dụng mặc định của quản trị viên.


3
Cảm ơn, nó giúp. Một điều tôi sẽ thay đổi: sử dụng args=[object.pk]thay vì args=[object.id]. Nó bao gồm trường hợp phổ biến hơn, khi trường khóa chính có tên khác hơn id.
rình rập

5
Câu trả lời tốt. FYI bất cứ ai sử dụng một django gần đây hơn sẽ cần phải thay đổi object._meta.module_name để object._meta.model_name
Jagu

Cảm ơn bạn rất nhiều từ một người mới chơi django. object._meta.app_labelcuối cùng hãy để tôi lấy tên cho ứng dụng xác thực của django. Đó là auth, ví dụ reverse(admin:auth_user_change, args=[object.id])để nhảy đến trang thay đổi người sử dụng
Gret

2
Hãy chắc chắn để thay đổi đối tượng để obj. Anh chàng này đang viết một biểu tượng được xây dựng dành riêng.
Kevin Parker

17

Có một cách khác cho các phiên bản sau, ví dụ như trong 1.10 :

{% 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>

Một optscái gì đó như mymodelinstance._metahoặcMyModelClass._meta

Một điều đáng chú ý là bạn không thể truy cập trực tiếp các thuộc tính gạch dưới trong các mẫu Django (như thế {{ myinstance._meta }}) để bạn phải truyền optsđối tượng từ chế độ xem dưới dạng bối cảnh mẫu.


2
Các url tài liệu đã thay đổi! Xem: docs.djangoproject.com/en/1.9/ref/contrib/admin/ory
Wim Feijen

12

Về cơ bản giống như câu trả lời của Mike Ramirez, nhưng đơn giản và gần gũi hơn về kiểu dáng với get_absolute_urlphương pháp tiêu chuẩn django :

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

11

Đối với django pre 1.1, nó rất đơn giản (ví dụ trang web quản trị mặc định):

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

8
Với cách đặt tên mới, đó là quản trị viên:% s_% s_change
Teebes

3

Nếu bạn đang sử dụng 1.0, hãy thử tạo một templatetag tùy chỉnh trông như thế này:

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,
    )

sau đó chỉ cần sử dụng {% adminpageurl my_object%} trong mẫu của bạn (đừng quên tải templatetag trước)


1

Tôi đã giải quyết điều này bằng cách thay đổi biểu thức thành:

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

Điều này yêu cầu / giả định rằng url url conf có tên cho trình xử lý url "admin", chủ yếu là tên đó là "django-admin",

tức là trong url gốc conf:

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

Nó dường như đang hoạt động, nhưng tôi không chắc về sự sạch sẽ của nó.


2
Điều này hoạt động cho 1.0, nhưng sẽ không hoạt động cho 1.1, có giải pháp tốt hơn: xem câu trả lời của Alex Koshelev.
Carl Meyer

Trên thực tế tôi đã thử nó và nó không hoạt động, và anh ấy nói nó là 1.0, phải không?
hasen

Cú pháp đã thay đổi trong 1.1 với sự ra đời của url namespacing: docs.djangoproject.com/en/dev/topics/http/urls/...
sleepyjames

-1

Đây là một tùy chọn khác, sử dụng các mô hình:

Tạo một mô hình cơ sở (hoặc chỉ thêm phương thức admin_link vào một mô hình cụ thể)

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

Kế thừa từ mô hình cơ sở đó

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

Sử dụng nó trong một mẫu

{{ user.admin_link }}

Hoặc xem

user.admin_link()

2
Tôi không nghĩ rằng đây là một giải pháp tốt. Xây dựng một URL với định dạng chuỗi là một thói quen xấu. Vui lòng sử dụng ngược ().
guettli
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.