21

我有一个像下面这样的模型。创建实例后,我想向感兴趣的一方发送电子邮件:

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='admin@example.com',
            recipient_list=[instance.notify_email,]
        )
signals.post_save.connect(new_stop_created, sender=TrainStop)

但是,该reverse调用仅返回 URL 的路径部分。示例:/stops/9/status/。我需要一个完整的 URL,例如http://example.com/stops/9/status/. 我将如何检索当前网站的主机名和端口(对于不使用端口 80 的测试实例)?

我最初的想法是通过一个变量来提供settings.py它,然后我可以根据需要访问它。但是,认为有人可能有更强有力的建议。

4

2 回答 2

5

正如 yedpodtrzitko 所提到的,有站点框架,但是,正如您所提到的,它在很大程度上是手动设置。

需要在 settings.py 中进行设置,但它只比设置站点稍微少一点手动。(它可以处理多个域,就像站点和SITE_ID设置一样)。

有一个替换 get_absolute_url的想法,这将使这样的事情变得更容易,尽管我认为它的实现存在同样的问题(如何获取域、方案 [http vs https] 等)。

我一直在玩弄一个中间件的想法,它检查传入的请求并根据 HTTP HOST 标头值的频率构造某种“最可能的域”设置。或者它可以单独为每个请求设置此设置,因此您始终可以使用当前域。我还没有认真研究它,但这是一个想法。

于 2010-11-11T02:05:01.737 回答
4

为了获取当前站点,有对象站点:

如果您无权访问请求对象,则可以使用 Site 模型管理器的 get_current() 方法。然后,您应该确保您的设置文件确实包含 SITE_ID 设置。此示例与上一个示例等效:

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

更多信息:http ://docs.djangoproject.com/en/dev/ref/contrib/sites/

于 2010-11-11T00:01:15.937 回答