2012-05-02 12 views
22

Antes que nada, gracias por leer mi pregunta.Django - Cómo obtener la URL del administrador a partir de la instancia modelo

Estoy tratando de enviar un correo electrónico a un usuario cuando se guarda una nueva instancia de modelo y quiero que el correo electrónico incluya un enlace a la página de administración para esa instancia de modelo. ¿Hay alguna forma de obtener la URL correcta? Me imagino que Django debe tener esa información almacenada en algún lugar.

Respuesta

26

Este Django snippet debe hacer:

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

El self se refiere a la clase de modelo de los padres, es decir, self.id se refiere a la instancia del objeto id. También puede configurarlo como property en el modelo pegando el decorador @property sobre la firma del método.

+0

Estas respuestas no parecen estar funcionando. Acabo de volver "/ admin/tracker/order/2 /". ¿Cómo obtengo el nombre de host? – Greg

+0

@Greg Por supuesto, 'get_admin_url()' anterior le proporciona la parte que va después del nombre de host. Utilice el marco de Django [sitios] (https://docs.djangoproject.com/en/dev/ref/contrib/sites/) para obtener apropiadamente el nombre de host del sitio actual. Luego, prefímalo al resultado de 'get_admin_url()'. –

+1

Funciona bien en 1.8, también – GergelyPolonkai

33

No estoy tratando de estafar a @JosvicZammit, pero usar ContentType es el enfoque equivocado aquí. Es solo una consulta DB desperdiciada. Puede obtener la información requieren del atributo _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 tendría si pudiera hacer con eficacia muestras de código en los comentarios. Esto hubiera sido un desastre total. Noté que Josvic tenía la respuesta, y él recibió crédito por ello, así que, sin ofender, pero realmente no estoy seguro de por qué te importa un año después del hecho. –

4

sólo tiene que utilizar éste revestimiento que es también pitón 3 listas:

from django.core.urlresolvers import reverse 

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

Más sobre esto en el documento Django administrador del sitio, reversing admin urls.

+0

Debe ser 'self._meta.model_name' en lugar de' self._meta.module_name'. – nedned

+0

Gracias @nedned, fixing – radtek

+0

Solo porque es posible: 'reverse ('admin: {m.app_label} _ {m.model_name} _change'.format (m = self._meta), args = [self.pk]) ' – batisteo

7

Esto da el mismo resultado que fragmento de Josvic Zammit, pero no golpea la base de datos:

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

change attr' module_name' by 'model_name' (' module_name' is undefined) – ppython

+1

Django 1.8 renombró el atributo 'module_name' a 'model_name' en el metaobjeto de un modelo. Se ha actualizado el fragmento de código ... ¡gracias! –

2

Por lo tanto, la combinación de las respuestas de Chris, Josvic y Josh, que aquí es un método de copiar y pegar se puede añadir en su modelo (probado en 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,)) 
Cuestiones relacionadas