2012-05-02 8 views
22

Prima di tutto, grazie per aver letto la mia domanda.Django - Come ottenere l'URL di amministratore dall'istanza di modello

Sto cercando di inviare un messaggio di posta elettronica a un utente quando viene salvata una nuova istanza di modello e voglio che l'e-mail includa un collegamento alla pagina di amministrazione per tale istanza di modello. C'è un modo per ottenere l'URL corretto? Immagino che Django debba avere quell'informazione immagazzinata da qualche parte.

risposta

26

Questo Django snippet dovrebbe fare:

from django.core import urlresolvers 
from django.contrib.contenttypes.models import ContentType 
from django.db import models 

class MyModel(models.Model): 

    def get_admin_url(self): 
     content_type = ContentType.objects.get_for_model(self.__class__) 
     return urlresolvers.reverse("admin:%s_%s_change" % (content_type.app_label, content_type.model), args=(self.id,)) 

La self riferisce alla classe del modello genitore, cioè self.id riferisce alla istanza dell'oggetto id. È inoltre possibile impostarlo come property sul modello attaccando il decoratore @property sopra la firma del metodo.

+0

Queste risposte non sembrano funzionare. Torno indietro "/ admin/tracker/order/2 /". Come ottengo il nome host? – Greg

+0

@Greg Ovviamente, 'get_admin_url()' in alto ti fornisce la parte che segue il nome host. Utilizzare il framework Django [sites] (https://docs.djangoproject.com/en/dev/ref/contrib/sites/) per ottenere in modo appropriato il nome host del sito corrente. Quindi anteponilo al risultato di 'get_admin_url()'. –

+1

Funziona bene anche in 1.8, – GergelyPolonkai

33

Non tentare di strappare @JosvicZammit, ma utilizzare ContentType è l'approccio sbagliato qui. È solo una query DB sprecata. È possibile ottenere le informazioni richieste dalle attributo _meta:

from django.core.urlresolvers import reverse 

info = (model_instance._meta.app_label, model_instance._meta.model_name) 
admin_url = reverse('admin:%s_%s_change' % info, args=(model_instance.pk,)) 
+5

Lo farei se potessi effettivamente fare esempi di codice nei commenti. Questo sarebbe stato un disastro assoluto. Ho notato che Josvic aveva la risposta, e ne ha avuto credito, quindi, senza offesa, ma non sono sicuro del motivo per cui dovresti prenderti cura di quasi un anno dopo il fatto. –

4

basta usare questo uno di linea che è anche Python 3 pronto:

from django.core.urlresolvers import reverse 

reverse('admin:{0}_{1}_change'.format(self._meta.app_label, self._meta.model_name), args=(self.pk,)) 

Più su questo in Django amministratore del sito doc, reversing admin urls.

+0

Dovrebbe essere 'self._meta.model_name' piuttosto che' self._meta.module_name'. – nedned

+0

Grazie @nedned, che fissa – radtek

+0

Proprio perché è possibile: 'reverse ('admin: {m.app_label} _ {m.model_name} _change'.format (m = self._meta), args = [self.pk]) ' – batisteo

7

Questo dà lo stesso risultato di frammento di Josvic Zammit, ma non colpisce il database:

from django.core import urlresolvers 
from django.db import models 

class MyModel(models.Model): 

    def get_admin_url(self): 
     return urlresolvers.reverse("admin:%s_%s_change" % (self._meta.app_label, self._meta.model_name), args=(self.id,)) 
+0

cambia attr' module_name' di 'model_name' (' module_name' non è definito) – ppython

+1

Django 1.8 ha rinominato l'attributo 'module_name' in 'model_name' nel meta oggetto di un modello. Snippet di codice aggiornato ... grazie! –

2

Così, combinando le risposte di Chris, Josvic e Josh, ecco un metodo di copia-incolla è possibile aggiungere nella il tuo modello (testato su Django 1.8.3).

def get_admin_url(self): 
    """the url to the Django admin interface for the model instance""" 
    from django.core.urlresolvers import reverse 
    info = (self._meta.app_label, self._meta.model_name) 
    return reverse('admin:%s_%s_change' % info, args=(self.pk,)) 
Problemi correlati