2010-11-10 13 views
15

Tengo un modelo como el siguiente. Cuando se crea una instancia, quiero enviar un correo electrónico a una parte interesada:Django: Obteniendo la URL absoluta sin acceso a un objeto de solicitud

class TrainStop(models.Model): 
    name = models.CharField(max_length=32) 
    notify_email = models.EmailField(null=True, blank=True) 

def new_stop_created(sender, instance, created, *args, **kwargs): 

    # Only for new stops 
    if not created or instance.id is None: return 

    # Send the status link 
    if instance.notify_email: 
     send_mail(
      subject='Stop submitted: %s' % instance.name, 
      message='Check status: %s' % reverse('stop_status', kwargs={'status_id':str(instance.id),}), 
      from_email='[email protected]', 
      recipient_list=[instance.notify_email,] 
     ) 
signals.post_save.connect(new_stop_created, sender=TrainStop) 

Sin embargo, la llamada reverse sólo devuelve la parte de ruta de la URL. Ejemplo: /stops/9/status/. Necesito una URL completa como http://example.com/stops/9/status/. ¿Cómo voy a recuperar el nombre de host y el puerto (para las instancias de prueba que no usan el puerto 80) del sitio web actual?

Mi idea inicial era hacer que esto esté disponible a través de una variable en settings.py a la que podría acceder cuando sea necesario. Sin embargo, pensó que alguien podría tener una sugerencia más robusta.

Respuesta

4

Hay el marco sitios, como yedpodtrzitko mencionado, pero, como usted ha mencionado, es en gran medida una configuración manual.

Requiere una configuración en settings.py, pero es solo un poco menos manual que la configuración de sitios. (Puede manejar múltiples dominios, tan bien como sitios y la configuración SITE_ID puede).

Hay una idea para replacing get_absolute_url que facilitaría cosas como esta, aunque creo que su implementación adolece del mismo problema (cómo obtener el dominio, esquema [http vs https], etc.).

He estado jugando con la idea de un middleware que examina las solicitudes entrantes y construye una configuración de "dominio más probable" de algún tipo en función de la frecuencia del valor del encabezado HTTP HOST. O tal vez podría establecer esta configuración en cada solicitud individualmente, por lo que siempre podría tener el dominio actual para trabajar. No he llegado al punto de analizarlo seriamente, pero es un pensamiento.

+0

"si no se molestan en configurarlo, mi aplicación no se molestará en trabajar para ellos", pero eso no es útil "¿Cómo se puede llamar para indicar que un" requisito "es" no útil "? Es un requisito fácil para declarar. Tiene que ser puesto en la configuración y eso es el final. Gran parte de Django requiere configuración o no funciona. ¿Por qué esta aplicación debe ser "mágica" y no requiere configuración? Si no puede confiar en el usuario, entonces, van a hacer algo más para subvertir la aplicación también, ¿no? Al igual que alterar el código.Simplemente indique la configuración requerida y termine con ella. No waffle –

+0

Esto es cierto, pero quería decir más que no es útil para nuestra discusión actual hacia un método de detección de dominio confiable. Tienes razón, sin embargo, es tonto de mi parte decir que "no podemos confiar en el usuario" así. – eternicode

+0

No puede detectar el dominio sin la solicitud, y 'reverse' o' {% url%} '. Cualquier otra cosa ** requiere ** una configuración. Es sencillo. No hay razón para dudar sobre eso. Requiere la configuración y listo. –

4

Para conseguir sitio actual no hay objeto de sitio:

Si usted no tiene acceso al objeto solicitud, puede utilizar el método get_current() del gestor del modelo de sitio. Debería entonces asegurarse de que su archivo de configuración contenga la configuración SITE_ID. Este ejemplo es equivalente a la anterior:

from django.contrib.sites.models import Site 

def my_function_without_request(): 
    current_site = Site.objects.get_current() 
    if current_site.domain == 'foo.com': 
     # Do something 
     pass 
    else: 
     # Do something else. 
     pass 

Más información: http://docs.djangoproject.com/en/dev/ref/contrib/sites/

+0

Actualmente no utilizo el framework de sitios. Parece que va a ser más trabajo de lo que vale solo para obtener el dominio actual, que tiene que configurarse manualmente de todos modos. Gracias de cualquier forma. –

+0

Estoy confundido. Esto es precisamente para lo que sirve el marco de trabajo de sitios, y le da la capacidad de establecer esta información una vez y tenerla disponible en todas partes. También es mucho más fácil de editar cuando está en el DB que, como sugirió, en el archivo de configuración. Entonces, ¿cuál es exactamente el problema? –

+2

De la documentación de los sitios: "Úselo si su única instalación de Django alimenta más de un sitio y necesita diferenciar entre esos sitios de alguna manera". Este no es un proyecto con múltiples sitios web, así que estoy implementando un modelo para almacenar esta información que es excesivo para mi situación. –

Cuestiones relacionadas