Abrufen der Django-Administrator-URL für ein Objekt

168

Vor Django 1.0 gab es eine einfache Möglichkeit, die Administrator-URL eines Objekts abzurufen, und ich hatte einen kleinen Filter geschrieben, den ich folgendermaßen verwenden würde: <a href="{{ object|admin_url }}" .... > ... </a>

Grundsätzlich habe ich die URL-Umkehrfunktion mit dem Namen der Ansicht verwendet 'django.contrib.admin.views.main.change_stage'

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

um die URL zu bekommen.

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

Wie kann ich das in Django 1.0 machen? (oder 1.1 für diese Angelegenheit, da ich versuche, auf die neueste Version im SVN zu aktualisieren).

hasen
quelle

Antworten:

61

Ich hatte ein ähnliches Problem, bei dem ich versuchte anzurufen, reverse('admin_index')und bekam ständig django.core.urlresolvers.NoReverseMatchFehler.

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

Ich hatte dies in meinen URL-Mustern:

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

Das bringt die Admin-Bildschirme zum Laufen, ist aber die veraltete Methode. Ich musste es so ändern:

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

Sobald ich das getan hatte, begann all die Güte, die in den Reversing Admin URLs- Dokumenten versprochen wurde, zu funktionieren.

bskinnersf
quelle
Genial, dies hat ein weiteres Problem behoben, das ich hatte, weil die Methode get_urls () von ModelAdmin nicht aufgerufen wurde. Vielen Dank!
Arnaud
8
beste URL für dieses Problem: docs.djangoproject.com/de/dev/ref/contrib/admin/…
Dingo
4
Diese "Antwort" ist nicht korrekt. Sie zeigt nur, wie Sie die Admin-App ordnungsgemäß zu Ihrer App hinzufügen, wodurch ein anderes Problem des Autors gelöst wurde. Die eigentliche Antwort auf die eigentliche Frage ist unten - von Markmütz
Declan Shanaghy
Außerdem muss die Administrationsoberfläche für das Modell registriert sein, da sonst die URL nicht vorhanden ist.
Flimm
412

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: Dokumentation

Markmütz
quelle
1
markmuetz - Ist das irgendwo in den offiziellen Django-Dokumenten? (Wie verwende ich Admin-Reverse-URLs in Vorlagen)? Wenn nicht, sollte es sein.
Shacker
7
Shacker - Es ist alles in den Dokumenten ... nur nicht an einem Ort. Das Template-Tag "url" ist hier dokumentiert . Im Abschnitt "Neu in Django 1.1:" sagen die Dokumente, dass URLs mit Namespace in Ordnung sind, und verweisen auf den Abschnitt über URL-Namespaces . Wenn Sie alles zusammenhalten, können Sie die Administratoranwendung einfach in Vorlagen referenzieren. NB Ich erinnere mich, dass die Dokumente anders waren, als ich die Antwort schrieb.
Markmütz
3
Wissen Sie, wie Sie einen Link zur "Liste" der Auswahlmöglichkeiten erhalten? Beispiel: Wenn "{% url admin: polls_choice_add%}" "/ admin / polls / choice / add" ergibt, was wäre das Äquivalent, das mir "/ admin / polls / choice" geben würde?
DarwinSurvivor
2
{% url admin: polls_choice_changelist%} gibt die URL '/ admin / polls / choice' zurück
luc
34
Das Umkehren einer Administrator-URL ist derzeit hier vollständig dokumentiert: https://docs.djangoproject.com/de/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__())

Dies ähnelt der Lösung von hansen_j, verwendet jedoch URL-Namespaces , wobei admin: der Standard-Anwendungsnamespace des Administrators ist.

Mike Ramirez
quelle
3
Danke, es hilft. Eine Sache würde ich ändern: verwenden args=[object.pk]statt args=[object.id]. Es wird häufiger behandelt, wenn das Primärschlüsselfeld einen anderen Namen als hat id.
Stiel
5
Gute Antwort. Zu Ihrer Information
Jagu
Vielen Dank von einem Django-Neuling. object._meta.app_labelLassen Sie mich letztendlich den Namen für Djangos eigene Authentifizierungs-App erhalten. Es ist authzum Beispiel reverse(admin:auth_user_change, args=[object.id]), um zur Benutzerseite zu wechseln
Gret
2
Stellen Sie sicher, dass Sie das Objekt in obj ändern. Dieser Typ hat gerade ein reserviertes Symbol eingebaut.
Kevin Parker
17

Es gibt einen anderen Weg 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 optsist so etwas wie mymodelinstance._metaoderMyModelClass._meta

Ein Problem ist, dass Sie nicht direkt in Django-Vorlagen (wie {{ myinstance._meta }}) auf Unterstrichattribute zugreifen können, sodass Sie das optsObjekt aus der Ansicht als Vorlagenkontext übergeben müssen.

Anentropisch
quelle
2
Die URL des Dokuments hat sich geändert! Siehe: docs.djangoproject.com/de/1.9/ref/contrib/admin/…
Wim Feijen
12

Im Wesentlichen das Gleiche wie die Antwort von Mike Ramirez, jedoch einfacher und stilistisch näher an der Django-Standardmethode get_absolute_url:

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

Für Django vor 1.1 ist es einfach (für die Standardinstanz der Admin-Site):

reverse('admin_%s_%s_change' % (app_label, model_name), args=(object_id,))
Alex Koshelev
quelle
8
Mit dem neuen Namespace ist es admin:% s_% s_change
Teebes
3

Wenn Sie 1.0 verwenden, erstellen Sie ein benutzerdefiniertes Templatetag, das folgendermaßen 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,
    )

Verwenden Sie dann einfach {% adminpageurl my_object%} in Ihrer Vorlage (vergessen Sie nicht, zuerst das Templatetag zu laden).

DarwinÜberlebender
quelle
1

Ich habe dies gelöst, indem ich den Ausdruck geändert habe in:

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

Dies erfordert / setzt voraus, dass die Root-URL conf einen Namen für den URL-Handler "admin" hat, hauptsächlich "django-admin".

dh in der root url conf:

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

Es scheint zu funktionieren, aber ich bin mir nicht sicher, ob es sauber ist.

hasen
quelle
2
Dies funktioniert für 1.0, aber nicht für 1.1, was eine bessere Lösung bietet: siehe Alex Koshelevs Antwort.
Carl Meyer
Eigentlich habe ich es versucht und es hat nicht funktioniert, und er sagte, es ist für 1.0, nein?
Hasen
Die Syntax hat sich in 1.1 mit der Einführung des URL-Namespaces geändert
sleepyjames
-1

Hier ist eine weitere Option unter Verwendung von Modellen:

Erstellen Sie ein Basismodell (oder fügen Sie einfach die admin_link-Methode zu einem bestimmten Modell hinzu)

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

Von diesem Basismodell erben

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

Verwenden Sie es in einer Vorlage

{{ user.admin_link }}

Oder ansehen

user.admin_link()
Ian Cohen
quelle
2
Ich denke nicht, dass dies eine gute Lösung ist. Das Erstellen einer URL mit Zeichenfolgenformatierung ist eine schlechte Angewohnheit. Bitte verwenden Sie reverse ().
Guettli