2009-03-29 8 views
123

Bevor Django 1.0 es eine einfache Möglichkeit war die Admin-URL eines Objekts zu erhalten, und ich hatte einen kleinen Filter geschrieben, dass ich so verwenden würde: <a href="{{ object|admin_url }}" .... > ... </a>Ersten url Django Admin für ein Objekt

Im Grunde war ich die uRL Reverse-Funktion mit der Ansicht Namen 'django.contrib.admin.views.main.change_stage'

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

ist die uRL zu erhalten.

Wie Sie vielleicht vermutet haben, versuche ich auf die neueste Version von Django zu aktualisieren, und dies ist eines der Hindernisse, auf die ich gestoßen bin, dass die Methode zum Abrufen der Admin-URL nicht mehr funktioniert.

Wie kann ich dies in Django 1.0 tun? (oder 1.1 für diese Angelegenheit, wie ich versuche, auf die neueste Version in der SVN zu aktualisieren).

Antwort

48

Ich hatte ein ähnliches Problem, bei dem ich versuchen würde, reverse('admin_index') anrufen und django.core.urlresolvers.NoReverseMatch Fehler immer konstant war.

Es stellte sich heraus, dass ich die alten Format-Admin-URLs in meiner urls.py-Datei hatte.

Ich hatte in meinem urlpatterns:

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

, die die Admin-Bildschirme arbeiten wird, ist aber die veraltete Art und Weise tun. Ich brauchte es, um dies zu ändern:

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

Nachdem ich das getan hätte, all die Güte, die in dem Reversing Admin URLs docs versprochen wurden zu arbeiten begann.

+0

Ehrfürchtig, dies behebt ein weiteres Problem, das ich mit der Methode get_urls() von ModelAdmin hatte, die nicht aufgerufen wurde. Vielen Dank! – Arnaud

+7

beste URL für dieses Problem: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#reversing-admin-urls – Dingo

+3

Diese "Antwort" ist nicht korrekt, es zeigt nur, wie Sie den Administrator ordnungsgemäß hinzufügen App zu Ihrer App, die ein anderes Problem gelöst hat, das der Autor hatte. Die eigentliche Antwort auf die eigentliche Frage ist unten - von markmuetz –

1

Ich löste dies durch den Ausdruck zu ändern:

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

Dies erfordert/geht davon aus, dass die Stamm-URL conf einen Namen für den „admin“ URL-Handler hat, vor allem, dass der Namen „django-admin“,

dh in der Stamm-uRL conf:

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

Es scheint zu funktionieren, aber ich bin nicht sicher, seine Reinheit.

+1

Dies funktioniert für 1.0, wird aber für 1.1 nicht funktionieren, die eine bessere Lösung hat: siehe Alex Koshelevs Antwort. –

+0

Eigentlich habe ich es versucht und es hat nicht funktioniert, und er sagte, es ist für 1.0, nein? – hasen

+0

Syntax wurde in 1.1 mit der Einführung von URL-Namespacing geändert: http://docs.djangoproject.com/en/dev/topics/http/urls/#topics-http-reversing-url-namespaces – sleepyjames

9

Für pre 1.1 django es (für Standard-Admin-Site-Instanz) ist einfach:

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

Mit dem neuen Namespacing ist es admin:% s_% s_change – Teebes

3

Wenn Sie 1.0 verwenden, versuchen Sie eine benutzerdefinierte TemplateTag machen, die wie folgt aussieht:

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

dann benutzen Sie einfach {% adminpageurl my_object%} in Ihrer Vorlage (nicht zu vergessen die TemplateTag zuerst zu laden)

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

Dies ist ähnlich Lösung des hansen_j außer dass es nutzt url namespaces, admin: ist die Standardanwendung Namespace des Administrators.

+2

Danke, es hilft. Eine Sache, die ich ändern würde: Verwenden Sie 'args = [object.pk]' anstelle von 'args = [object.id]'. Es deckt häufiger den Fall ab, wenn das Primärschlüsselfeld einen anderen Namen als 'id' hat. – stalk

+4

Gute Antwort. FYI jemand, der einen neueren Django benutzt, muss sich ändern object._meta.module_name zu object._meta.model_name – Jagu

+0

Großes Dankeschön von einem Django-Neuling. 'object._meta.app_label' lassen Sie mich endlich den Namen für djangos eigene Authentifizierungs-App bekommen.Es ist 'auth', zum Beispiel' reverse (admin: auth_user_change, args = [object.id]) '' um zur Änderungs-Benutzerseite zu springen – Gret

302

Sie können den URL-Resolver direkt in einer Vorlage verwenden, Sie müssen keinen eigenen Filter schreiben. Z.B.

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Ref: Documentation

+1

markmuetz - Ist das in der offiziellen Django-Dokumentation irgendwo? (Wie verwendet man umgekehrte URLs in Vorlagen)? Wenn nicht, sollte es sein. – shacker

+6

Shacker - Es ist alles in der Docs ... nur nicht an einem Ort. Das Schablonen-Tag "url" ist [hier] dokumentiert (http://docs.djangoproject.com/en/1.2/ref/templates/builtins/#url). Im Abschnitt "Neu in Django 1.1:" heißt es in den Dokumenten, dass Namespaced-URLs in Ordnung sind und verweist Sie auf [den Abschnitt zu URL-Namespaces] (http://docs.djangoproject.com/en/1.2/topics/http/urls)/# topics-http-reversing-URL-Namespaces). Wenn Sie alles miteinander verbinden, können Sie in Templates einfach auf die Admin-Anwendung verweisen. N.B Ich erinnere mich, dass die Dokumente anders waren, als ich die Antwort schrieb. – markmuetz

+3

Wissen Sie, wie Sie einen Link zur "Liste" der Auswahlmöglichkeiten erhalten? Beispiel: Wenn "{% url admin: polls_choice_add%}" "/ admin/polls/choice/add" gibt, was wäre das Äquivalent, das mir "/ admin/polls/choice" geben würde? – DarwinSurvivor

0

Hier ist eine weitere Option, mit Hilfe von Modellen:

ein Basismodell erstellen (oder nur die ADMIN_LINK Verfahren auf ein bestimmtes Modell hinzufügen)

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 

Vererben von diesem Basismodell

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

es die Verwendung in einer Vorlage

{{ user.admin_link }} 

Or Ansicht

user.admin_link() 
+0

Ich denke nicht, dass dies eine gute Lösung ist. Es ist eine schlechte Angewohnheit, eine URL mit String-Formatierung zu erstellen. Bitte verwenden Sie die umgekehrte(). – guettli

11

Es gibt eine andere Art und Weise für die späteren Versionen, zum Beispiel 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> 

Wo opts ist so etwas wie mymodelinstance._meta oder MyModelClass._meta

Eine gotcha ist, dass Sie nicht Strich zugreifen können direkt in Django-Vorlagen-Attribute (wie {{ myinstance._meta }}) so müssen Sie das opts Objekt in der Ansicht als Vorlagenkontext übergeben.

+2

Die Dokument-URL hat sich geändert! Siehe: https://docs.djangoproject.com/de/1.9/ref/contrib/admin/#reversing-admin-urls –

7

Wesentlichen die gleiche wie Mike Ramirez Antwort, aber einfacher und näher in Stilistik Standard get_absolute_url Methode django:

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