Как я могу получить полный / абсолютный 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, и он даст вам полный.
По умолчанию request.get_full_path()
возвращается абсолютный URL-адрес для , но вы можете передать ему относительный URL-адрес в качестве первого аргумента, чтобы преобразовать его в абсолютный URL-адрес.
{{ request.build_absolute_uri }}{{ object.get_absolute_url }}
указать параметры) вы можете просто сделать это: - и heyho, полный URL.
{% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}
потому что {{ request.build_absolute_uri }}
имел косую черту и {{ object.get_absolute_url }}
начал с косой черты, что привело к двойной косой черты в URL.
Если вы хотите использовать его вместе с reverse()
вами, вы можете сделать это:request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))
url_name
а не view_name
)
def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
Вы также можете использовать 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 сайта по умолчанию.
django.contrib.sites
в вашей INSTALLED_APPS
, он не попал в БД на всех, и предоставить информацию , основанную на объекте запроса (см get_current_site )
build_absolute_uri
все еще выглядит как более простое и чистое решение.
Если вы не можете получить доступ к нему, request
вы не можете использовать его get_current_site(request)
в соответствии с рекомендациями, приведенными здесь. Вы можете использовать комбинацию нативной платформы Sites и get_absolute_url
вместо этого. Настройте хотя бы один сайт в администраторе, убедитесь, что в вашей модели есть метод 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
request
на None
или позвонив по телефону get_current_site(None)
.
Если вы не хотите использовать базу данных, вы можете сделать это с настройкой. Затем используйте контекстный процессор, чтобы добавить его к каждому шаблону:
# 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
объекта для получения доменного имени. В этом случае вы должны sites
вместо этого использовать платформу, которая получает имя домена из базы данных. Смотрите django-absoluteuri
, упомянуто в разделе «см. Также» README этого пакета PyPI.
Чтобы создать полную ссылку на другую страницу из шаблона, вы можете использовать это:
{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}
request.META.HTTP_HOST дает имя хоста, а url дает относительное имя. Затем шаблонизатор объединяет их в полный URL-адрес.
http
в данном контексте) и ://
часть URL, поэтому он не предоставит полный URL-адрес .
Еще один способ. Вы можете использовать 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 }}
HttpRequest.build_absolute_uri(request)
эквивалентно request.build_absolute_uri()
не так ли?
Изучите Request.META
входящий словарь. Я думаю, что он имеет имя сервера и порт сервера.
Это сработало для меня в моем шаблоне:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Мне нужен был полный URL, чтобы передать его в функцию js fetch. Я надеюсь, что это поможет вам.
Я знаю, что это старый вопрос. Но я думаю, что люди все еще сталкиваются с этим.
Есть несколько библиотек, которые дополняют стандартную функциональность Django. Я попробовал несколько. Мне нравится следующая библиотека при обратной ссылке на абсолютные URL:
https://github.com/fusionbox/django-absoluteuri
Еще один, который мне нравится, потому что вы можете легко собрать домен, протокол и путь:
https://github.com/RRMoelker/django-full-url
Эта библиотека позволяет вам просто написать то, что вы хотите в своем шаблоне, например:
{{url_parts.domain}}
Если вы используете django REST framework, вы можете использовать функцию reverse из 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
request=request
. Также не похоже, что запрос задокументирован здесь. Docs.djangoproject.com/en/1.9/ref/urlresolvers/#reverse
Я понял:
wsgiref.util.request_uri(request.META)
Получите полный URI со схемой, хостом, путем к порту и запросом.
Также есть 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.build_absolute_uri()
идеально подходит, если у вас есть доступ request
, и sites
инфраструктура великолепна, если разные URL-адреса указывают на разные базы данных.
Однако мой вариант использования был немного другим. Мой промежуточный сервер и рабочий сервер имеют доступ к одной и той же базе данных, но get_current_site
оба вернули первый site
в базе данных. Чтобы решить эту проблему, вы должны использовать какую-то переменную окружения. Вы можете использовать 1) переменную окружения (что-то вроде os.environ.get('SITE_URL', 'localhost:8000')
) или 2) разные SITE_ID
s для разных серверов И разные settings.py .
Надеюсь, кто-то найдет это полезным!
Я наткнулся на эту тему, потому что я искал абсолютный URI для страницы успеха. request.build_absolute_uri()
дал мне URI для моего текущего представления, но чтобы получить URI для моего успешного просмотра, я использовал следующее ....
request.build_absolute_uri (обратный ( 'success_view_name'))
Вы также можете использовать:
import socket
socket.gethostname()
Это работает нормально для меня,
Я не совсем уверен, как это работает. Я полагаю, что это немного более низкий уровень и будет возвращать имя хоста вашего сервера, которое может отличаться от имени хоста, используемого вашим пользователем для перехода на вашу страницу.