รับ URL ผู้ดูแลระบบ Django สำหรับวัตถุ


168

ก่อน Django 1.0 มีวิธีง่าย ๆ ในการรับ url ของวัตถุและฉันได้เขียนตัวกรองขนาดเล็กที่ฉันใช้เช่นนี้ <a href="{{ object|admin_url }}" .... > ... </a>

โดยทั่วไปฉันใช้ฟังก์ชันย้อนกลับ URL ด้วยชื่อมุมมอง 'django.contrib.admin.views.main.change_stage'

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

เพื่อรับ URL

อย่างที่คุณอาจคาดเดาได้ฉันกำลังพยายามอัปเดตเป็น Django เวอร์ชันล่าสุดและนี่เป็นหนึ่งในอุปสรรคที่ฉันเจอวิธีการรับ URL ผู้ดูแลระบบไม่ทำงานอีกต่อไป

ฉันจะทำสิ่งนี้ใน django 1.0 ได้อย่างไร (หรือ 1.1 สำหรับเรื่องนั้นเพราะฉันพยายามอัปเดตเป็นเวอร์ชั่นล่าสุดใน svn)

คำตอบ:


61

ฉันมีปัญหาที่คล้ายกันซึ่งฉันจะพยายามโทรหาreverse('admin_index')และได้รับdjango.core.urlresolvers.NoReverseMatchข้อผิดพลาดอยู่ตลอดเวลา

ปรากฎว่าฉันมี URL รูปแบบเก่าของผู้ดูแลระบบในไฟล์ urls.py ของฉัน

ฉันมีสิ่งนี้ใน urlpatterns ของฉัน:

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

ซึ่งทำให้หน้าจอผู้ดูแลระบบทำงานได้ แต่เป็นวิธีที่เลิกใช้แล้ว ฉันต้องการเปลี่ยนเป็น:

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

เมื่อฉันทำเช่นนั้นความดีทั้งหมดที่ได้รับสัญญาในเอกสารการย้อนกลับ URL ของผู้ดูแลระบบเริ่มทำงาน


ยอดเยี่ยมปัญหานี้ได้รับการแก้ไขอีกปัญหาหนึ่งที่ฉันมีเมื่อใช้เมธอด get_urls () ของ ModelAdmin ขอบคุณ!
Arnaud

8
URL ที่ดีที่สุดสำหรับปัญหานี้: docs.djangoproject.com/en/dev/ref/contrib/admin/…
Dingo

4
"คำตอบ" นี้ไม่ถูกต้องเพียงแสดงวิธีเพิ่มแอปผู้ดูแลระบบให้กับแอปของคุณอย่างถูกต้องซึ่งแก้ไขปัญหาที่แตกต่างจากที่ผู้เขียนมี คำตอบที่แท้จริงสำหรับคำถามจริงอยู่ด้านล่าง - จาก markmuetz
Declan Shanaghy

นอกจากนี้คุณต้องมีส่วนต่อประสานผู้ดูแลระบบที่ลงทะเบียนสำหรับรุ่นมิเช่นนั้นจะไม่มี URL
Flimm

413

คุณสามารถใช้ตัวแก้ไข URL โดยตรงในเทมเพลตโดยไม่จำเป็นต้องเขียนตัวกรองของคุณเอง เช่น

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Ref: เอกสารประกอบ


1
markmuetz - นี่เป็นเอกสารอย่างเป็นทางการของ Django หรือเปล่า? (วิธีใช้ URL ย้อนกลับของผู้ดูแลระบบในแม่แบบ) ถ้าไม่มันควรจะเป็น
shacker

7
shacker - ทั้งหมดอยู่ในเอกสาร ... ไม่ได้อยู่ในที่เดียว "URL" แท็กแม่แบบเป็นเอกสารที่นี่ ในส่วน "ใหม่ใน Django 1.1:" เอกสารบอกว่า URL namespaced จะมีการปรับและจุดให้คุณส่วนที่เกี่ยวกับ namespaces การรวมทั้งหมดเข้าด้วยกันช่วยให้คุณสามารถอ้างอิงแอปพลิเคชันผู้ดูแลระบบได้อย่างง่ายดายในเทมเพลต NB ฉันจำได้ว่าเอกสารนั้นแตกต่างกันเมื่อฉันเขียนคำตอบ
markmuetz

3
คุณรู้วิธีรับลิงค์ไปยัง "รายการ" ของตัวเลือกหรือไม่? ตัวอย่าง: ถ้า "{% url ผู้ดูแลระบบ: polls_choice_add%}" ให้ "/ admin / polls / choice / add" อะไรจะเทียบเท่าที่จะให้ฉัน "/ admin / polls / choice"?
DarwinSurvivor

2
{% url ผู้ดูแลระบบ: polls_choice_changelist%} ส่งคืน url '/ admin / polls / choice'
luc

35
การย้อนกลับ URL ของผู้ดูแลระบบมีการบันทึกไว้อย่างสมบูรณ์แล้วที่นี่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__())

สิ่งนี้คล้ายกับโซลูชันของ hansen_j ยกเว้นว่าจะใช้เนมสเปซ urlผู้ดูแลระบบ: เป็นเนมสเปซเริ่มต้นของผู้ดูแลระบบ


3
ขอบคุณมันช่วยได้ สิ่งหนึ่งที่ผมจะเปลี่ยนงาน: ใช้งานแทนargs=[object.pk] มันครอบคลุมกรณีร่วมกันมากขึ้นเมื่อข้อมูลคีย์หลักมีชื่ออื่นมากกว่าargs=[object.id] id
ก้าน

5
คำตอบที่ดี. ทุกคนที่ใช้ django เมื่อเร็ว ๆ นี้จะต้องเปลี่ยน object._meta.module_name เป็น object._meta.model_name
Jagu

ขอบคุณมากจากมือใหม่ django object._meta.app_labelให้ฉันได้รับชื่อที่สุดสำหรับแอพการพิสูจน์ตัวตนของ django มันเป็นauthเช่นreverse(admin:auth_user_change, args=[object.id])กระโดดไปยังหน้าเปลี่ยนผู้
Gret

2
โปรดเปลี่ยนวัตถุให้เป็น obj ผู้ชายคนนี้เป็นมากกว่าการเขียนสัญลักษณ์ในตัวที่สงวนไว้
Kevin Parker

17

มีวิธีอื่นสำหรับรุ่นที่ใหม่กว่าเช่นใน 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>

ไหนoptsเป็นสิ่งที่ต้องการmymodelinstance._metaหรือMyModelClass._meta

หนึ่ง gotcha คือคุณไม่สามารถเข้าถึงแอตทริบิวต์ขีดล่างโดยตรงในแม่แบบ Django (เช่น{{ myinstance._meta }}) ดังนั้นคุณต้องผ่านoptsวัตถุจากมุมมองเป็นบริบทเทมเพลต


2
URL ของเอกสารมีการเปลี่ยนแปลง! ดู: docs.djangoproject.com/en/1.9/ref/contrib/admin/…
Wim Feijen

12

โดยพื้นฐานแล้วเหมือนกับคำตอบของไมค์รามิเรซ แต่เรียบง่ายกว่าและใกล้เคียงกับสไตลิสส์ถึงget_absolute_urlวิธีมาตรฐาน django :

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

11

สำหรับ 1.1 ก่อน django มันง่าย (สำหรับอินสแตนซ์ไซต์ผู้ดูแลระบบเริ่มต้น):

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

8
ด้วยการกำหนดชื่อใหม่ให้เป็นผู้ดูแลระบบ:% s_% s_change
Teebes

3

หากคุณใช้ 1.0 ให้ลองสร้างเทมเพลตแท็กที่กำหนดเองซึ่งมีลักษณะดังนี้:

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

จากนั้นใช้ {% adminpageurl my_object%} ในเทมเพลตของคุณ (อย่าลืมโหลดเทมเพลตก่อน)


1

ฉันแก้ไขได้โดยเปลี่ยนการแสดงออกเป็น:

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

สิ่งนี้ต้องการ / สมมติว่า url url conf มีชื่อสำหรับตัวจัดการ url "admin" ส่วนใหญ่ชื่อนั้นคือ "django-admin"

เช่นใน conf url url:

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

ดูเหมือนว่าจะใช้งานได้ แต่ฉันไม่แน่ใจเรื่องความสะอาด


2
ใช้งานได้กับ 1.0 แต่จะใช้ไม่ได้กับ 1.1 ซึ่งมีทางออกที่ดีกว่า: ดูคำตอบของ Alex Koshelev
Carl Meyer

ที่จริงฉันลองแล้วมันใช้งานไม่ได้และเขาบอกว่ามันใช้งานได้ 1.0 ใช่มั้ย
hasen

ไวยากรณ์มีการเปลี่ยนแปลงใน 1.1 ด้วยการแนะนำ url namespacing: docs.djangoproject.com/en/dev/topics/http/urls/…
sleepyjames

-1

นี่คือตัวเลือกอื่นโดยใช้โมเดล:

สร้างโมเดลพื้นฐาน (หรือเพิ่มเมธอด admin_link ให้กับโมเดลเฉพาะ)

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

รับช่วงจากโมเดลพื้นฐานนั้น

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

ใช้ในเทมเพลต

{{ user.admin_link }}

หรือดู

user.admin_link()

2
ฉันไม่คิดว่านี่เป็นทางออกที่ดี การสร้าง URL ด้วยการจัดรูปแบบสตริงเป็นนิสัยที่ไม่ดี โปรดใช้ย้อนกลับ ()
guettli
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.