Как я могу получить полный/абсолютный URL (с доменом) в Django?

Как я могу получить полный/абсолютный URL (например, https://example.com/some/path) в Django без модуля Sites? Это просто глупо... Мне не нужно запрашивать мою БД, чтобы поймать URL!

Я хочу использовать его с reverse().

Ответ 1

Используйте удобный request.build_absolute_uri() метод по запросу, передайте ему относительный URL-адрес, и он даст вам полный.

По умолчанию возвращается абсолютный URL для request.get_full_path(), но вы можете передать ему относительный URL в качестве первого аргумента, чтобы преобразовать его в абсолютный URL.

Ответ 2

Если вы хотите использовать его с помощью reverse(), вы можете сделать это: request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))

Ответ 3

Вы также можете использовать 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-адрес сайта по умолчанию.

Ответ 4

Если вы не можете получить доступ к 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

Ответ 5

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

# 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>

Ответ 6

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" %}

Эти значки должны, надеюсь, оставаться в курсе последних событий:

PyPI Travis CI

В представлении вы можете, конечно, использовать request.build_absolute_uri.

Ответ 7

Чтобы создать полную ссылку на другую страницу из шаблона, вы можете использовать это:

{{ request.META.HTTP_HOST }}{% url 'views.my_view' my_arg %}

request.META.HTTP_HOST указывает имя хоста, а url указывает относительное имя. Затем механизм шаблонов объединяет их в полный URL-адрес.

Ответ 8

Изучите словарь Request.META, который входит. Я думаю, что у него есть имя сервера и порт сервера.

Ответ 9

Еще один способ. Вы можете использовать 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 }}

Ответ 10

На ваш взгляд, просто сделайте следующее:

base_url =  "{0}://{1}{2}".format(request.scheme, request.get_host(), request.path)

Ответ 11

Я знаю, что это старый вопрос. Но я думаю, что люди все еще сталкиваются с этим.

Существует несколько библиотек, которые дополняют функциональность Django по умолчанию. Я попробовал несколько. Мне нравится следующая библиотека при обратном обращении к абсолютным URL:

https://github.com/fusionbox/django-absoluteuri

Еще один, который мне нравится, потому что вы можете легко объединить домен, протокол и путь:

https://github.com/RRMoelker/django-full-url

Эта библиотека позволяет вам просто писать то, что вы хотите в своем шаблоне, например:

{{url_parts.domain}}

Ответ 12

Попробуйте использовать следующий код:

{{ request.scheme }}://{{ request.META.HTTP_HOST }}

Ответ 13

Если вы используете 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

Ответ 14

Я понял:

wsgiref.util.request_uri(request.META)

Получить полный uri с помощью схемы, хоста, пути порта и запроса.

Ответ 15

Это сработало для меня в моем шаблоне:

{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url  'equipos:marca_filter' %}

Мне нужен был полный URL, чтобы передать его в функцию js fetch. Я надеюсь, что это поможет вам.

Ответ 16

Также есть 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()

Подкласс это и теперь вы можете использовать его везде.

Ответ 17

request.get_host() предоставит вам домен.

Ответ 18

Вы можете попробовать "request.get_full_path()"

Ответ 19

Вы также можете использовать:

import socket
socket.gethostname()

Это отлично работает для меня,

Я не совсем уверен, как это работает. Я считаю, что это немного более низкий уровень и вернет ваше имя хоста сервера, которое может отличаться от имени хоста, используемого вашим пользователем, чтобы перейти на вашу страницу.