Django: получение абсолютного URL без доступа к объекту запроса

У меня есть модель, подобная приведенной ниже. Когда экземпляр создается, я хочу отправить электронное письмо заинтересованному лицу:

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)

Однако вызов reverse возвращает только путь к URL-адресу. Пример: /stops/9/status/. Мне нужен полный URL, например http://example.com/stops/9/status/. Как я могу получить имя хоста и порт (для тестовых экземпляров, которые не используют порт 80) текущего веб-сайта?

Моя первоначальная мысль заключалась в том, чтобы сделать это доступным через переменную в settings.py, которую я мог бы затем получить по мере необходимости. Однако, подумал, что у кого-то может быть более надежное предложение.

Ответы

Ответ 1

Там основы сайтов, как упоминал йедподтцитко, но, как вы уже упоминали, это очень ручная настройка.

Требуется установка в settings.py, но она немного менее ручная, чем настройка сайтов. (Он может обрабатывать несколько доменов, а также сайты и параметр SITE_ID).

Есть идея заменить get_absolute_url, что упростит ситуацию, хотя я думаю, что ее реализация страдает от одной и той же проблемы (как получить домен, схему [http vs https] и т.д.).

Я играл с идеей промежуточного программного обеспечения, которое анализирует входящие запросы и строит параметр "наиболее вероятный домен" определенного типа, основанный на частоте значения заголовка HTTP HOST. Или, возможно, он может установить этот параметр для каждого запроса индивидуально, так что вы всегда можете работать с текущим доменом. Я не дошел до серьезного взгляда на него, но это мысль.

Ответ 2

Для получения текущего сайта есть объект Сайт:

Если у вас нет доступа к объекту запроса, вы можете использовать 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/