Bir nesne için Django yönetici URL'sini alma


168

Django 1.0 önce bir nesnenin yönetici url almak için kolay bir yol vardı ve ben böyle kullanacağım küçük bir filtre yazmıştı: <a href="{{ object|admin_url }}" .... > ... </a>

Temelde görünüm adı olmak ile url ters işlevini kullanıyordum 'django.contrib.admin.views.main.change_stage'

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

url almak için.

Tahmin edebileceğiniz gibi, Django'nun en son sürümüne güncellemeye çalışıyorum ve bu, karşılaştığım engellerden biri, yönetici URL'sini elde etmek için bu yöntem artık çalışmıyor.

Bunu django 1.0'da nasıl yapabilirim? (veya bu konu için 1.1, svn son sürümüne güncellemeye çalışıyorum gibi).

Yanıtlar:


61

Aramaya çalıştığım benzer bir sorunum vardı reverse('admin_index')ve sürekli django.core.urlresolvers.NoReverseMatchhatalar alıyordum .

Urls.py dosyamda eski biçim yönetici URL'lerine sahip olduğum anlaşılıyor.

Bu benim urlpatterns vardı:

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

Bu da yönetici ekranlarının çalışmasını sağlar, ancak bunu yapmanın kullanımdan kaldırılmasıdır. Ben bunu değiştirmek gerekiyordu:

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

Bunu yaptıktan sonra, Geri Dönüşüm Yönetici URL'leri dokümanlarında vaat edilen tüm iyilikler çalışmaya başladı.


Harika, bu denilen ModelAdmin get_urls () yöntemi ile yaşıyordu başka bir sorunu düzeltildi. Teşekkürler!
Arnaud


4
Bu "cevap" doğru değil, sadece uygulamanın uygulamanıza nasıl düzgün şekilde ekleneceğini gösterir, bu da yazarın sahip olduğu farklı bir sorunu çözdü. Asıl soruya gerçek cevap aşağıda - markmuetz'den
Declan Shanaghy

Ayrıca, model için kayıtlı yönetici arayüzüne sahip olmanız gerekir, aksi takdirde URL mevcut olmaz.
Flimm

413

URL çözümleyiciyi doğrudan bir şablonda kullanabilirsiniz, kendi filtrenizi yazmanıza gerek yoktur. Örneğin

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Ref: Belgeler


1
markmuetz - Bu resmi Django belgelerinde herhangi bir yerde mi? (şablonlarda yönetici ters URL'leri nasıl kullanılır?) Değilse, olmalı.
shacker

7
shacker - Hepsi dokümanlarda ... tek bir yerde değil. "URL" şablon etiketi burada belgelenmiştir . "Django 1.1'de Yeni:" bölümünde dokümanlar, ad boşluklu URL'lerin iyi olduğunu söylüyor ve sizi URL ad alanlarındaki bölüme yönlendiriyor . Hepsini bir araya getirmek, yönetici uygulamasına şablonlarda kolayca başvurmanızı sağlar. Not Cevabı yazdığımda belgelerin farklı olduğunu hatırlıyorum.
markmuetz

3
Seçimlerin "listesine" nasıl link verileceğini biliyor musun? Örnek: "{% url admin: polls_choice_add%}", "/ admin / polls / choice / add" değerini verirse, bana "/ admin / polls / choice" verecek eşdeğer ne olur?
DarwinSurvivor

2
{% url admin: polls_choice_changelist%}, '/ admin / polls / choice' URL'sini döndürür
luc

35
Bir yönetici URL'sini tersine çevirmek şu anda burada tam olarak belgelenmiştir 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__())

Bu, urnsen ad alanlarını kullanması dışında hansen_j'nin çözümüne benzer , admin: yöneticinin varsayılan uygulama ad alanıdır .


3
Teşekkürler, yardımcı olur. Değiştireceğim bir şey: args=[object.pk]yerine kullanın args=[object.id]. Birincil anahtar alanı başka bir ada sahip olduğunda daha yaygın olan durumu kapsar id.
SAP

5
İyi cevap. FYI daha yeni bir django kullanan herkes object._meta.module_name'i object._meta.model_name olarak değiştirmelidir
Jagu

Django acemi büyük teşekkürler. object._meta.app_labelsonuçta django'nun kendi kimlik doğrulama uygulamasının adını alalım. Bu var authörneğin, reverse(admin:auth_user_change, args=[object.id])değişim kullanıcı sayfasına atlamak için
Gret

2
Nesneyi obj olarak değiştirdiğinizden emin olun. Bu adam, yerleşik bir yerleşik sembol yazıyor.
Kevin Parker

17

Daha sonraki sürümler için başka bir yol var, örneğin 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>

Nereye optsbenziyor mymodelinstance._metaya daMyModelClass._meta

Bir gotcha, alt çizgi özniteliklerine doğrudan Django şablonlarında (gibi {{ myinstance._meta }}) erişememeniz, böylece optsnesneyi görünümden şablon bağlamı olarak geçirmeniz gerekir.


2
Dokümanlar URL'si değişti! Bakınız: docs.djangoproject.com/tr/1.9/ref/contrib/admin/…
Wim Feijen

12

Aslında Mike Ramirez'in cevabı ile aynı, ancak django standart get_absolute_urlyöntemine stilistik olarak daha basit ve daha yakın :

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 öncesi django için basittir (varsayılan yönetici sitesi örneği için):

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

8
Yeni ad alanı ile admin:% s_% s_change
Teebes

3

1.0 kullanıyorsanız, şuna benzer özel bir şablon etiketi oluşturmayı deneyin:

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

ardından şablonunuzda {% adminpageurl my_object%} kullanın (önce şablon etiketini yüklemeyi unutmayın)


1

Ifade şu şekilde değiştirerek bunu çözdüm:

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

Bu, root url conf'in "admin" url işleyicisi için bir ada sahip olduğunu gerektirir / varsayar, esas olarak bu ad "django-admin",

yani kök url conf:

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

Çalışıyor gibi görünüyor, ama temizliğinden emin değilim.


2
Bu 1.0 için çalışıyor, ancak daha iyi bir çözümü olan 1.1 için işe yaramayacak: Alex Koshelev'in cevabına bakın.
Carl Meyer

Aslında denedim ve işe yaramadı ve 1.0 olduğunu söyledi, değil mi?
290

Sözdizimi, url ad alanı ile 1.1'de değişti: docs.djangoproject.com/en/dev/topics/http/urls/…
sleepyjames

-1

İşte modelleri kullanan başka bir seçenek:

Bir temel model oluşturun (veya yalnızca belirli bir modele admin_link yöntemini ekleyin)

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

Bu temel modelden devral

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

Bir şablonda kullanın

{{ user.admin_link }}

Veya görüntüle

user.admin_link()

2
Bunun iyi bir çözüm olduğunu düşünmüyorum. Dize biçimlendirmeli bir URL oluşturmak kötü bir alışkanlıktır. Lütfen reverse () kullanın.
guettli
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.