Как я могу получить URL (с протоколом и доменом) в Django (без запроса)?
Я хочу отправить почту в задание cron. Почта должна содержать
ссылку на мое приложение.
В задании cron у меня нет объекта запроса и я не могу использовать request.build_absolute_uri().
AFAIK рамки сайта могут помочь здесь. Но не дает мне протокол (http vs https)?
Мое приложение многократно используется и иногда размещается на http, а иногда и на сайтах https.
Обновление
Я ищу обычный путь джанго. Создание пользовательских настроек возможно, но предпочтительным является решение со стандартами django.
Связанная проблема: https://code.djangoproject.com/ticket/16734
Ответы
Ответ 1
Для этого есть специальный стандартный модуль - Site Framework.
В нем добавлена модель сайта, в которой описывается конкретный сайт. Эта модель имеет поле domain
для домена проекта и name
- общедоступное имя сайта.
Вы связываете свои модели с сайтами. Например:
from django.db import models
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(max_length=200)
# ...
site = models.ForeignKey(Site, on_delete=models.CASCADE)
Когда вам нужно создать URL-адрес для объекта, вы можете использовать что-то вроде следующего кода:
>>> from django.contrib.sites.models import Site
>>> obj = MyModel.objects.get(id=3)
>>> obj.get_absolute_url()
'/mymodel/objects/3/'
>>> Site.objects.get_current().domain
'example.com'
>>> 'https://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())
'https://example.com/mymodel/objects/3/'
Таким образом, вы можете иметь несколько доменов и контент, распространяемый между ними.
Даже если у вас есть только один домен, я рекомендую использовать его для достижения хорошего стандартного удобного способа сохранения настроек домена.
Installatioin довольно просто:
Ответ 2
TL; DR: Нет никакого "стандартного" метода "Django-ish", но принцип DRY, продвигаемый платформой, предполагает единое хранилище конфигурации, поэтому пользовательская настройка кажется быть хорошим способом.
По умолчанию Django может обслуживать любое количество доменов из одного экземпляра, а HTTP-запрос (точнее, заголовок HTTP_HOST
) - это единственное, что Django использует для определения текущего хоста.
Поскольку ваши задания cron явно выходят из цикла HTTP, вы должны хранить свой домен где-то в настройках...
# settings.py
DEFAULT_DOMAIN = 'https://foobar.com'
# or, depending on your configuration:
DEFAULT_DOMAIN = 'https://{}'.format(ALLOWED_HOSTS[0])
... с крошечным процессором контекста, чтобы упростить обработку шаблонов:
# yourapp/context_processors.py
from django.conf import settings
def default_domain(request):
return {'default_domain': settings.DEFAULT_DOMAIN}
... и затем используйте его в своих письмах:
# yourapp/templates/email/body.html
<a href="{{ default_domain }}{% url 'target' %}">Click here</a>
В качестве альтернативы вы можете использовать фреймворк sites
, но если вы обслуживаете один домен, решение на основе настроек выглядит намного проще и чище для меня.