Django:在不访问请求obj的情况下获取绝对URL

2024-06-20 15:02:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个像下面的模型。创建实例时,我希望向相关方发送电子邮件:

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中的一个变量使其可用,然后我可以根据需要访问该变量。不过,我想有人会有更有力的建议。


Tags: 实例instancenameidtruenewmodelsemail
2条回答

要获取当前站点,有个对象站点:

If you don’t have access to the request object, you can use the get_current() method of the Site model’s manager. You should then ensure that your settings file does contain the SITE_ID setting. This example is equivalent to the previous one:

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/

正如yedpodtrzitko所提到的,有一个站点框架,但是,正如您所提到的,它是一个非常手动的设置。

在setting s.py中需要一个设置,但它只比设置站点稍微少一些手动操作。(它可以处理多个域,就像处理站点一样,SITE_ID设置也可以)。

有一个关于replacing get_absolute_url的想法,这将使类似的事情变得更容易,尽管我认为它的实现也遇到了同样的问题(如何获取域、scheme[http vs http s]等等)。

我一直在考虑一个中间件的概念,它检查传入的请求,并根据HTTP主机头的值的频率构造某种“最有可能的域”设置。或者它可以对每个请求单独设置此设置,这样您就可以始终使用当前域。我还没有到认真研究的地步,但这是一个想法。

相关问题 更多 >