Как я могу получить полный/абсолютный URL (например, https://example.com/some/path
) в Django без модуля Sites? Это просто глупо... Мне не нужно запрашивать мою БД, чтобы поймать URL!
Я хочу использовать его с reverse()
.
Как я могу получить полный/абсолютный URL (например, https://example.com/some/path
) в Django без модуля Sites? Это просто глупо... Мне не нужно запрашивать мою БД, чтобы поймать URL!
Я хочу использовать его с reverse()
.
Используйте удобный request.build_absolute_uri() метод по запросу, передайте ему относительный URL-адрес, и он даст вам полный.
По умолчанию возвращается абсолютный URL для request.get_full_path()
, но вы можете передать ему относительный URL в качестве первого аргумента, чтобы преобразовать его в абсолютный URL.
Если вы хотите использовать его с помощью reverse()
, вы можете сделать это: request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
Вы также можете использовать get_current_site
как часть приложения для сайтов (from django.contrib.sites.models import get_current_site
). Он принимает объект запроса и по умолчанию задает объект сайта, который вы настроили с помощью SITE_ID
в settings.py, если запрос None
. Подробнее в документации для с использованием инфраструктуры сайтов
например.
from django.contrib.sites.shortcuts import get_current_site
request = None
full_url = ''.join(['http://', get_current_site(request).domain, obj.get_absolute_url()])
Он не такой компактный/опрятный, как request.build_absolute_url()
, но он может использоваться, когда объекты запроса недоступны, и у вас есть URL-адрес сайта по умолчанию.
Если вы не можете получить доступ к request
, вы не можете использовать get_current_site(request)
, как рекомендуется в некоторых решениях здесь. Вместо этого вы можете использовать комбинацию структуры родных сайтов и get_absolute_url
. Настройте хотя бы один Site в админке, убедитесь, что ваша модель имеет get_absolute_url(), то:
>>> from django.contrib.sites.models import Site
>>> domain = Site.objects.get_current().domain
>>> obj = MyModel.objects.get(id=3)
>>> path = obj.get_absolute_url()
>>> url = 'http://{domain}{path}'.format(domain=domain, path=path)
>>> print(url)
'http://example.com/mymodel/objects/3/'
https://docs.djangoproject.com/en/dev/ref/contrib/sites/#getting-the-current-domain-for-full-urls
Если вы не хотите попасть в базу данных, вы можете сделать это с настройкой. Затем используйте контекстный процессор, чтобы добавить его в каждый шаблон:
# settings.py (Django < 1.9)
...
BASE_URL = 'http://example.com'
TEMPLATE_CONTEXT_PROCESSORS = (
...
'myapp.context_processors.extra_context',
)
# settings.py (Django >= 1.9)
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
# Additional
'myapp.context_processors.extra_context',
],
},
},
]
# myapp/context_processors.py
from django.conf import settings
def extra_context(request):
return {'base_url': settings.BASE_URL}
# my_template.html
<p>Base url is {{ base_url }}.</p>
django-fullurl
Если вы пытаетесь сделать это в шаблоне Django, я выпустил крошечный пакет PyPI django-fullurl
, чтобы вы могли заменить url
и static
с тегами fullurl
и fullstatic
, например:
{% load fullurl %}
Absolute URL is: {% fullurl "foo:bar" %}
Another absolute URL is: {% fullstatic "kitten.jpg" %}
Эти значки должны, надеюсь, оставаться в курсе последних событий:
В представлении вы можете, конечно, использовать request.build_absolute_uri
.
Чтобы создать полную ссылку на другую страницу из шаблона, вы можете использовать это:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST указывает имя хоста, а url указывает относительное имя. Затем механизм шаблонов объединяет их в полный URL-адрес.
Изучите словарь Request.META
, который входит. Я думаю, что у него есть имя сервера и порт сервера.
Еще один способ. Вы можете использовать build_absolute_uri()
в своем view.py
и передать его в шаблон.
view.py
def index(request):
baseurl = request.build_absolute_uri()
return render_to_response('your-template.html', { 'baseurl': baseurl })
ваш-template.html
{{ baseurl }}
На ваш взгляд, просто сделайте следующее:
base_url = "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)
Я знаю, что это старый вопрос. Но я думаю, что люди все еще сталкиваются с этим.
Существует несколько библиотек, которые дополняют функциональность Django по умолчанию. Я попробовал несколько. Мне нравится следующая библиотека при обратном обращении к абсолютным URL:
https://github.com/fusionbox/django-absoluteuri
Еще один, который мне нравится, потому что вы можете легко объединить домен, протокол и путь:
https://github.com/RRMoelker/django-full-url
Эта библиотека позволяет вам просто писать то, что вы хотите в своем шаблоне, например:
{{url_parts.domain}}
Попробуйте использовать следующий код:
{{ request.scheme }}://{{ request.META.HTTP_HOST }}
Если вы используете django REST framework, вы можете использовать обратную функцию от rest_framework.reverse
. Это имеет такое же поведение, как django.core.urlresolvers.reverse
, за исключением того, что для создания полного URL-адреса используется параметр запроса.
from rest_framework.reverse import reverse
# returns the full url
url = reverse('view_name', args=(obj.pk,), request=request)
# returns only the relative url
url = reverse('view_name', args=(obj.pk,))
Отредактировано, чтобы указать доступность только в инфраструктуре REST
Я понял:
wsgiref.util.request_uri(request.META)
Получить полный uri с помощью схемы, хоста, пути порта и запроса.
Это сработало для меня в моем шаблоне:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Мне нужен был полный URL, чтобы передать его в функцию js fetch. Я надеюсь, что это поможет вам.
Также есть ABSOLUTE_URL_OVERRIDES, доступный как настройка
https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides
Но это переопределяет get_absolute_url(), что может быть нежелательно.
Вместо того, чтобы устанавливать фреймворк сайтов только для этого или делать некоторые другие вещи, упомянутые здесь, которые опираются на объект запроса, я думаю, что лучшее решение - поместить это в models.py
Определите BASE_URL в settings.py, затем импортируйте его в models.py и создайте абстрактный класс (или добавьте его к тому, который вы уже используете), который определяет get_truly_absolute_url(). Это может быть так просто, как:
def get_truly_absolute_url(self):
return BASE_URL + self.get_absolute_url()
Подкласс это и теперь вы можете использовать его везде.
request.get_host()
предоставит вам домен.
Вы можете попробовать "request.get_full_path()"
Вы также можете использовать:
import socket
socket.gethostname()
Это отлично работает для меня,
Я не совсем уверен, как это работает. Я считаю, что это немного более низкий уровень и вернет ваше имя хоста сервера, которое может отличаться от имени хоста, используемого вашим пользователем, чтобы перейти на вашу страницу.