Як я можу отримати повну / абсолютну 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-адресу.
{{ 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)
як рекомендовано в деяких рішеннях тут. Ви можете використовувати комбінацію нативного фрейма Сайтів і 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 })
your-template.html
{{ baseurl }}
HttpRequest.build_absolute_uri(request)
еквівалентно request.build_absolute_uri()
чи не так?
Це працювало для мене в моєму шаблоні:
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
Мені потрібна була повна URL-адреса, щоб передати її до функції отримання js. Я сподіваюся, що це допоможе тобі.
Я знаю, це старе питання. Але я думаю, що люди все ще багато стикаються з цим.
Є кілька бібліотек, які доповнюють функціональність Django за замовчуванням. Я спробував кілька. Мені подобається наступна бібліотека при зворотному посиланні на абсолютні URL-адреси:
https://github.com/fusionbox/django-absoluteuri
Ще один мені подобається, тому що ви можете легко скласти домен, протокол і шлях:
https://github.com/RRMoelker/django-full-url
Ця бібліотека дозволяє просто записати те, що ви хочете у свій шаблон, наприклад:
{{url_parts.domain}}
Якщо ви використовуєте рамку django REST, ви можете використовувати функцію зворотного зв’язку від 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
Також в якості налаштування доступні 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 (зворотний ('ім'я успіху_відомості'))
Ви також можете використовувати:
import socket
socket.gethostname()
Це добре для мене,
Я не зовсім впевнений, як це працює. Я вважаю, що це трохи нижчий рівень, і він поверне ім’я хоста вашого сервера, яке може відрізнятися від імені хоста, використовуваного вашим користувачем для переходу на вашу сторінку.