web-dev-qa-db-fra.com

Obtenir Django URL d'administrateur d'un objet)

Avant Django 1.0, il existait un moyen facile d'obtenir l'URL d'administrateur d'un objet. J'avais écrit un petit filtre que j'utilisais comme ceci: <a href="{{ object|admin_url }}" .... > ... </a>

Fondamentalement, j’utilisais la fonction url reverse avec le nom de la vue étant '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 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 de l'administrateur ne fonctionne plus.

Comment puis-je faire cela dans Django 1.0? (Ou 1.1 d'ailleurs, car j'essaie de mettre à jour la dernière version dans le fichier svn).

153
hasen

J'ai eu un problème similaire où j'essayais d'appeler reverse('admin_index') et que je recevais constamment Django.core.urlresolvers.NoReverseMatch les erreurs.

Il se trouve que j'avais les urls de l'ancien format dans mon fichier urls.py.

J'ai eu ceci dans mon urlpatterns:

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

ce qui permet aux écrans d’administration de fonctionner mais c’est le moyen déconseillé de le faire. Je devais le changer en ceci:

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

Une fois que j'ai fait cela, tout le bien qui avait été promis dans la documentation Reversing URLs URL a commencé à fonctionner.

59
bskinnersf

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

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

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

93
Mike Ramirez

Il existe un autre moyen pour les versions ultérieures, par exemple dans 1.1 :

{% 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>

opts est quelque chose comme mymodelinstance._meta ou MyModelClass._meta

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

13
Anentropic

Identique à la réponse de Mike Ramirez, mais stylistique plus simple et plus proche de Django standard get_absolute_url méthode:

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

Pour les versions antérieures à 1.1 Django 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,))
10
Alex Koshelev

Si vous utilisez la version 1.0, essayez de créer un modèle personnalisé ressemblant à 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 mon_objet%} dans votre modèle (n'oubliez pas de charger le gabarit en premier)

3
DarwinSurvivor

J'ai résolu ceci en remplaçant l'expression par:

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 l'URL racine conf:

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

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

1
hasen

Voici une autre option, à l'aide de 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()
0
Ian Cohen