2009-03-29 11 views
123

Przed Django 1.0 było to prosty sposób, aby uzyskać adres administratora obiektu, a ja napisałem mały filtr użyję tak: <a href="{{ object|admin_url }}" .... > ... </a>Pierwsze Django Admin URL dla obiektu

Zasadniczo jestem przy użyciu funkcji odwrotnej url z nazwą widoku będącego 'django.contrib.admin.views.main.change_stage'

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

aby uzyskać adres URL.

Jak można się domyślić, staram się aktualizować do najnowszej wersji Django i jest to jedna z przeszkód, z jakimi się zetknąłem, ta metoda uzyskiwania adresu URL administratora już nie działa.

Jak mogę to zrobić w django 1.0? (lub 1.1 w tej kwestii, jak próbuję zaktualizować do najnowszej wersji w svn).

Odpowiedz

48

Miałem podobny problem, gdzie chciałbym spróbować zadzwonić reverse('admin_index') i ciągle coraz django.core.urlresolvers.NoReverseMatch błędów.

Okazuje się, że miałem adresy URL starego formatu w pliku urls.py.

miałem w moim tam wzorce:

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

który dostaje ekrany administratora działa, ale jest to nieaktualne sposób to zrobić. Musiałem zmienić go na to:

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

Raz zrobiłem, że wszystko dobro, które zostało obiecane w Reversing Admin URLs docs rozpoczął pracę.

+0

Awesome, to naprawiono inny problem, który miałem z get_urls() metoda ModelAdmin nie jest wywoływana. Dzięki! – Arnaud

+7

najlepszy adres URL dla tego problemu: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls – Dingo

+3

Ta "odpowiedź" nie jest poprawna pokazuje, jak poprawnie dodać administratora aplikacja do aplikacji, która rozwiązała inny problem niż ten, który miał autor. Prawdziwa odpowiedź na rzeczywiste pytanie znajduje się poniżej - od markmuetz –

1

Rozwiązałem to przez zmianę wyraz:

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

Wymaga to/zakłada, że ​​conf korzeń url ma nazwę „admin” obsługi zawartości, głównie że nazwa jest „django-admin”,

czyli w konf korzeń uRL:

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

wydaje się działać, ale nie jestem pewien jego czystości.

+1

To działa na 1.0, ale nie działa na 1.1, który ma lepsze rozwiązanie: patrz Alex Odpowiedź Koshelev'a. –

+0

Właściwie to wypróbowałem i nie zadziałało, a on powiedział, że to 1.0, nie? – hasen

+0

Składnia została zmieniona w wersji 1.1 po wprowadzeniu funkcji tworzenia nazw adresów URL: http://docs.djangoproject.com/en/dev/topics/http/urls/#topics-http-reversing-url-namespaces – sleepyjames

9

Dla wstępnego 1,1 django jest on prosty (na przykład Domyślna witryna admin):

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

Po dodaniu nowych nazw admin:% s_% s_change – Teebes

3

Jeśli używasz 1.0, spróbuj niestandardową templatetag, który wygląda tak:

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

następnie wystarczy użyć {% adminpageurl my_object%} w szablonie (nie zapomnij załadować templatetag pierwszy)

68
from django.core.urlresolvers import reverse 
def url_to_edit_object(object): 
    url = reverse('admin:%s_%s_change' %(object._meta.app_label, object._meta.model_name), args=[object.id]) 
    return u'<a href="%s">Edit %s</a>' %(url, object.__unicode__()) 

ten jest podobny do rozwiązania hansen_j za wyjątkiem tego, że używa url namespaces, admin: bycie nazw domyślnej aplikacji administratora za.

+2

Dzięki, pomaga. Jedna rzecz, którą chciałbym zmienić: użyj 'args = [object.pk]' zamiast 'args = [object.id]'. Obejmuje on bardziej typowy przypadek, gdy pole klucza podstawowego ma inną nazwę niż "id". – stalk

+4

Dobra odpowiedź. Dla każdego, kto używa nowszego django, trzeba zmienić object._meta.module_name na object._meta.model_name – Jagu

+0

Wielkie podziękowania dla nowicjuszy django. 'object._meta.app_label' pozwala mi ostatecznie uzyskać nazwę dla własnej aplikacji uwierzytelniającej django.To 'auth', na przykład' reverse (admin: auth_user_change, args = [object.id]) ', aby przejść do strony zmiany użytkownika – Gret

302

Możesz użyć narzędzia do rozwiązywania adresów URL bezpośrednio w szablonie, nie musisz wpisywać własnego filtru. Na przykład.

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Ref: Documentation

+1

markmuetz - Czy jest to oficjalna dokumentacja Django w dowolnym miejscu? (jak używać odwrotnych adresów URL w szablonach)? Jeśli nie, powinno być. – shacker

+6

shacker - To wszystko w dokumentach ... po prostu nie w jednym miejscu. Znacznik szablonu "url" jest udokumentowany [tutaj] (http://docs.djangoproject.com/en/1.2/ref/templates/builtins/#url). W sekcji "Nowości w Django 1.1:" dokumenty mówią, że adresy URL z podanymi nazwami są w porządku i wskazuje [sekcję o obszarach nazw URL] (http://docs.djangoproject.com/en/1.2/topics/http/urls/# topics-http-reversing-url-namespaces). Trzymanie tego wszystkiego razem pozwala łatwo odwoływać się do aplikacji administratora w szablonach. N.B Pamiętam, że dokumenty były inne, gdy pisałem odpowiedź. – markmuetz

+3

Czy wiesz, jak uzyskać link do "listy" wyborów? Przykład: jeśli "{% url admin: polls_choice_add%}" daje "/ admin/polls/choice/add", jaki byłby odpowiednik, który dałby mi "/ admin/polls/choice"? – DarwinSurvivor

0

Oto kolejna opcja, wykorzystujące modele:

Tworzenie modelu podstawowego (lub po prostu dodać metodę ADMIN_LINK do konkretnego modelu)

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 

Dziedziczy z tego modelu bazowego

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

Użyj go w szablonie

{{ user.admin_link }} 

Or zobacz

user.admin_link() 
+0

Nie sądzę, że jest to dobre rozwiązanie. Budowanie adresu URL za pomocą formatowania ciągów znaków jest złym nawykiem. Proszę użyć reverse(). – guettli

11

Jest inny sposób na późniejszych wersjach, na przykład 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> 

Gdzie opts jest coś mymodelinstance._meta lub MyModelClass._meta

Jeden Gotcha to nie można uzyskać dostępu podkreślenia atrybutów bezpośrednio w szablonach Django (jak {{ myinstance._meta }}), więc musisz przekazać obiekt opts z widoku jako kontekst szablonu.

+2

Adres URL dokumentu zmienił się! Zobacz: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#reversing-admin-urls –

7

Zasadniczo taka sama jak odpowiedź Mike'a Ramireza, ale prościej i bliżej w stylistyce do django standardowego get_absolute_url metody:

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