Obtenir l'URL d'administration Django pour un objet


168

Avant Django 1.0, il y avait un moyen simple d'obtenir l'URL d'administration d'un objet, et j'avais écrit un petit filtre que j'utiliserais comme ceci: <a href="{{ object|admin_url }}" .... > ... </a>

Fondamentalement, j'utilisais la fonction d'inversion d'URL avec le nom de la vue 'django.contrib.admin.views.main.change_stage'

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

pour obtenir l'url.

Comme vous l'avez peut-être deviné, j'essaie de mettre à jour vers la dernière version de Django, et c'est l'un des obstacles que j'ai rencontrés, cette méthode pour obtenir l'URL d'administration ne fonctionne plus.

Comment puis-je faire cela dans django 1.0? (ou 1.1 d'ailleurs, car j'essaye de mettre à jour vers la dernière version du svn).

Réponses:


61

J'ai eu un problème similaire où j'essayais d'appeler reverse('admin_index')et recevais constamment des django.core.urlresolvers.NoReverseMatcherreurs.

Il s'avère que j'avais l'ancien format des URL d'administrateur dans mon fichier urls.py.

J'avais ceci dans mes urlpatterns:

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

ce qui fait fonctionner les écrans d'administration, mais c'est la façon obsolète de le faire. J'avais besoin de le changer pour ceci:

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

Une fois que j'ai fait cela, tous les avantages promis dans les documents sur les URL d'administration inversées ont commencé à fonctionner.


Génial, cela a corrigé un autre problème que j'avais avec la méthode get_urls () de ModelAdmin qui n'était pas appelée. Merci!
— Arnaud

8
meilleure URL pour ce problème: docs.djangoproject.com/en/dev/ref/contrib/admin/…
— Dingo

4
Cette "réponse" n'est pas correcte, elle montre simplement comment ajouter correctement l'application d'administration à votre application, ce qui a résolu un problème différent que l'auteur avait. La vraie réponse à la question réelle est ci-dessous - de markmuetz
— Declan Shanaghy

En outre, vous devez avoir une interface d'administration enregistrée pour le modèle, sinon l'URL n'existera pas.
— Flimm le

412

Vous pouvez utiliser le résolveur d'URL directement dans un modèle, il n'est pas nécessaire d'écrire votre propre filtre. Par exemple

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Réf: Documentation


1
markmuetz - Est-ce que c'est dans la documentation officielle de Django quelque part? (comment utiliser les URL inversées d'administration dans les modèles)? Sinon, ça devrait l'être.
— shacker

7
shacker - Tout est dans la documentation ... mais pas au même endroit. La balise de modèle "url" est documentée ici . Dans la section "Nouveau dans Django 1.1:", la documentation indique que les URL à espaces de noms conviennent et vous renvoie à la section sur les espaces de noms d'URL . Coller tout cela vous permet de référencer facilement l'application d'administration dans des modèles. NB Je me souviens que les documents étaient différents lorsque j'ai écrit la réponse.
— markmuetz

3
Savez-vous comment obtenir un lien vers la «liste» des choix? Exemple: si "{% url admin: polls_choice_add%}" donne "/ admin / polls / choice / add" quel serait l'équivalent qui me donnerait "/ admin / polls / choice"?
— DarwinSurvivor

2
{% url admin: polls_choice_changelist%} renvoie l'url '/ admin / polls / choice'
— luc

35
L'inversion d'une URL d'administrateur est actuellement entièrement documentée ici 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__())

Ceci est similaire à la solution de hansen_j sauf qu'elle utilise les espaces de noms d'url , admin: étant l'espace de noms d'application par défaut de l'administrateur.


3
Merci, ça aide. Une chose que je changerais: utiliser args=[object.pk]au lieu de args=[object.id]. Il couvre le cas plus courant, lorsque le champ de clé primaire a un autre nom que id.
— tige

5
Bonne réponse. Pour info, toute personne utilisant un django plus récent devra changer object._meta.module_name en object._meta.model_name
— Jagu

Un grand merci d'un débutant django. object._meta.app_labellaissez-moi finalement obtenir le nom de la propre application d'authentification de django. C'est auth, par exemple, reverse(admin:auth_user_change, args=[object.id])pour passer à la page de changement d'utilisateur
— Gret

2
Assurez-vous de changer l'objet en obj. Ce type est en train d'écrire un symbole intégré réservé.
— Kevin Parker

17

Il existe un autre moyen pour les versions ultérieures, par exemple dans la 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>

Où optsest quelque chose comme mymodelinstance._metaouMyModelClass._meta

Un problème est que vous ne pouvez pas accéder aux attributs de soulignement directement dans les modèles Django (comme {{ myinstance._meta }}), vous devez donc passer l' optsobjet à partir de la vue en tant que contexte de modèle.


2
L'URL de la documentation a changé! Voir: docs.djangoproject.com/en/1.9/ref/contrib/admin/…
— Wim Feijen

12

Essentiellement la même que la réponse de Mike Ramirez, mais plus simple et plus proche en stylistique de la get_absolute_urlméthode standard de django :

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

11

Pour django pré 1.1, c'est simple (pour l'instance de site d'administration par défaut):

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

8
Avec le nouvel espace de noms, c'est admin:% s_% s_change
— Teebes

3

Si vous utilisez 1.0, essayez de créer une étiquette de modèle personnalisée qui ressemble à ceci:

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

puis utilisez simplement {% adminpageurl my_object%} dans votre template (n'oubliez pas de charger d'abord le templatetag)


1

J'ai résolu ce problème en changeant l'expression en:

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

Cela nécessite / suppose que la racine de l'url conf a un nom pour le gestionnaire d'url "admin", principalement ce nom est "django-admin",

c'est à dire dans la racine de l'url conf:

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

Il semble fonctionner, mais je ne suis pas sûr de sa propreté.


2
Cela fonctionne pour 1.0, mais ne fonctionnera pas pour 1.1, qui a une meilleure solution: voir la réponse d'Alex Koshelev.
— Carl Meyer

En fait, je l'ai essayé et cela n'a pas fonctionné, et il a dit que c'était pour 1.0, non?
— hasen

La syntaxe a changé dans la version 1.1 avec l'introduction de l'espace de noms des URL: docs.djangoproject.com/en/dev/topics/http/urls/…
— sleepyjames

-1

Voici une autre option, en utilisant des modèles:

Créez un modèle de base (ou ajoutez simplement la méthode admin_link à un modèle particulier)

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

Hériter de ce modèle de base

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

Utilisez-le dans un modèle

{{ user.admin_link }}

Ou voir

user.admin_link()

2
Je ne pense pas que ce soit une bonne solution. Construire une URL avec un formatage de chaîne est une mauvaise habitude. Veuillez utiliser reverse ().
— guettli
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.