Ottenere l'URL amministratore Django per un oggetto


168

Prima di Django 1.0 c'era un modo semplice per ottenere l'URL di amministrazione di un oggetto e avevo scritto un piccolo filtro che avrei usato in questo modo: <a href="{{ object|admin_url }}" .... > ... </a>

Fondamentalmente stavo usando la funzione inversa url con il nome della vista 'django.contrib.admin.views.main.change_stage'

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

per ottenere l'URL.

Come avrai intuito, sto cercando di aggiornare all'ultima versione di Django, e questo è uno degli ostacoli che ho riscontrato, quel metodo per ottenere l'URL di amministrazione non funziona più.

Come posso farlo in django 1.0? (o 1.1 del resto, come sto cercando di aggiornare all'ultima versione in svn).

Risposte:


61

Ho avuto un problema simile in cui avrei cercato di chiamare reverse('admin_index')e ricevevo costantemente django.core.urlresolvers.NoReverseMatcherrori.

Ho scoperto che avevo il vecchio formato admin urls nel mio file urls.py.

Ho avuto questo nei miei modelli:

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

che fa funzionare le schermate dell'amministratore ma è il modo deprecato di farlo. Ho dovuto cambiarlo in questo:

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

Una volta che l'ho fatto, tutta la bontà che era stata promessa nei documenti degli URL di amministrazione inversa ha iniziato a funzionare.


Fantastico, questo ha risolto un altro problema che avevo riscontrato con il metodo get_urls () di ModelAdmin che non veniva chiamato. Grazie!
Arnaud,

8
miglior url per questo problema: docs.djangoproject.com/en/dev/ref/contrib/admin/…
Dingo

4
Questa "risposta" non è corretta, mostra solo come aggiungere correttamente l'app di amministrazione alla tua app, il che ha risolto un diverso problema riscontrato dall'autore. La vera risposta alla domanda reale è di seguito - da markmuetz
Declan Shanaghy,

Inoltre, è necessario disporre di un'interfaccia di amministrazione registrata per il modello, altrimenti l'URL non esisterà.
Flimm,

412

Puoi utilizzare il risolutore URL direttamente in un modello, non è necessario scrivere il tuo filtro. Per esempio

{% url 'admin:index' %}

{% url 'admin:polls_choice_add' %}

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

{% url 'admin:polls_choice_changelist' %}

Rif: documentazione


1
markmuetz - È presente nei documenti ufficiali di Django da qualche parte? (come utilizzare gli URL inversi dell'amministratore nei modelli)? In caso contrario, dovrebbe essere.
shacker,

7
shacker - È tutto nei documenti ... solo non in un posto. Il tag del modello "url" è documentato qui . Nella sezione "Novità di Django 1.1:" i documenti affermano che gli URL con spazi dei nomi vanno bene e ti indirizzano alla sezione sugli spazi dei nomi degli URL . Incollare tutto insieme consente di fare riferimento facilmente all'applicazione admin nei modelli. NB Ricordo che i documenti sono diversi quando ho scritto la risposta.
markmuetz,

3
Sai come ottenere un link alla "lista" di scelte? Esempio: se "{% url admin: polls_choice_add%}" dà "/ admin / polls / choice / add" quale sarebbe l'equivalente che mi darebbe "/ admin / polls / choice"?
DarwinSurvivor,

2
{% url admin: polls_choice_changelist%} restituisce l'URL "/ admin / polls / choice"
luc

35
L'inversione di un URL amministratore è attualmente completamente documentata qui 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__())

Questo è simile alla soluzione di hansen_j tranne per il fatto che utilizza gli spazi dei nomi url , admin: essendo lo spazio dei nomi dell'applicazione predefinito dell'amministratore.


3
Grazie, aiuta Una cosa che cambierei: usare args=[object.pk]invece di args=[object.id]. Copre il caso più comune, quando il campo chiave primaria ha un nome diverso da id.
gambo

5
Buona risposta. Cordiali saluti, chiunque utilizzi un django più recente dovrà cambiare object._meta.module_name in object._meta.model_name
Jagu il

Grazie mille da un principiante django. object._meta.app_labellasciami in definitiva ottenere il nome per l'app di autenticazione di Django. È auth, ad esempio, reverse(admin:auth_user_change, args=[object.id])passare alla pagina di modifica dell'utente
Gret

2
Assicurati di cambiare l'oggetto in obj. Questo ragazzo sta finendo di scrivere un simbolo incorporato riservato.
Kevin Parker,

17

C'è un altro modo per le versioni successive, ad esempio 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>

Dov'è optsqualcosa come mymodelinstance._metaoMyModelClass._meta

Un problema è che non puoi accedere agli attributi di sottolineatura direttamente nei modelli di Django (come {{ myinstance._meta }}), quindi devi passare l' optsoggetto dalla vista come contesto del modello.


2
L'URL dei documenti è cambiato! Vedi: docs.djangoproject.com/en/1.9/ref/contrib/admin/…
Wim Feijen

12

Sostanzialmente uguale alla risposta di Mike Ramirez, ma più semplice e più vicina alla stilistica rispetto al get_absolute_urlmetodo standard di django :

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

11

Per pre 1.1 django è semplice (per l'istanza del sito di amministrazione predefinito):

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

8
Con il nuovo spazio dei nomi è admin:% s_% s_change
Teebes,

3

Se stai usando 1.0, prova a creare un templatetag personalizzato simile al seguente:

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

quindi usa {% adminpageurl my_object%} nel tuo modello (non dimenticare di caricare prima il templatetag)


1

Ho risolto questo cambiando l'espressione in:

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

Ciò richiede / presuppone che l'URL conf abbia un nome per il gestore dell'URL "admin", principalmente che sia "django-admin",

cioè nell'URL di root conf:

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

Sembra funzionare, ma non sono sicuro della sua pulizia.


2
Funziona con 1.0, ma non con 1.1, che ha una soluzione migliore: vedi la risposta di Alex Koshelev.
Carl Meyer,

In realtà l'ho provato e non ha funzionato, e ha detto che è per 1.0, no?
hasen

La sintassi è cambiata in 1.1 con l'introduzione del namespace url: docs.djangoproject.com/en/dev/topics/http/urls/…
sleepyjames

-1

Ecco un'altra opzione, usando i modelli:

Crea un modello di base (o aggiungi semplicemente il metodo admin_link a un modello particolare)

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

Eredita da quel modello base

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

Usalo in un modello

{{ user.admin_link }}

O visualizza

user.admin_link()

2
Non penso che questa sia una buona soluzione. Costruire un URL con la formattazione delle stringhe è una cattiva abitudine. Si prega di utilizzare reverse ().
Guettli,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.