Django에서 전체 / 절대 URL (도메인 포함)을 얻으려면 어떻게해야합니까?


379

Sites 모듈없이https://example.com/some/path Django에서 전체 / 절대 URL (예 : URL )을 얻으려면 어떻게 해야합니까? 그건 어리석은 일입니다 ... URL을 걸리기 위해 DB를 쿼리 할 필요가 없습니다!

와 함께 사용하고 싶습니다 reverse().


11
따로 : 사이트 모듈은 사이트 이름이 처음 필요할 때만 DB에 도달하면 결과는 모듈 또는 SiteManager.com을 다시 컴파일 할 때까지 계속 유지되는 모듈 변수 (SITE_CACHE)에 캐시됩니다. 메소드가 호출됩니다. 참조 : code.djangoproject.com/svn/django/tags/releases/1.3/django/...
대령 Sponsz

답변:


512

요청시 편리한 request.build_absolute_uri () 메소드를 사용 하고 상대 URL을 전달하면 전체 URL을 제공합니다.

기본적으로에 대한 절대 URL request.get_full_path()이 반환되지만 상대 URL을 첫 번째 인수로 전달하여 절대 URL로 변환 할 수 있습니다.


3
URL은 어떻습니까 : localhost / home / # / test ? localhost / home 만 볼 수 있습니다 . 날카로운 후 부품을 어떻게 볼 수 있습니까?
sergzach

41
# 이후의 모든 것이 서버로 전달되지 않으면 브라우저 전용 기능입니다.
Dmitry Shevchenko

69
매개 변수를 제공 할 수없는 템플릿에서는 다음 {{ request.build_absolute_uri }}{{ object.get_absolute_url }}과 같이하면됩니다.-및 heyho, 전체 URL.
odinho-Velmont

17
요청에 액세스 할 수 없으면 어떻게합니까? Django-REST-Framework의 시리얼 라이저 에서처럼?
minder

15
슬래시가 있고 슬래시로 시작하여 URL에 이중 슬래시가 발생 {% if request.is_secure %}https://{% else %}http://{% endif %}{{ request.get_host }}{{ object.get_absolute_url }}했기 때문에 사용해야 했습니다. {{ request.build_absolute_uri }}{{ object.get_absolute_url }}
xtranophilist

96

함께 사용하려면 reverse()다음을 수행하십시오.request.build_absolute_uri(reverse('view_name', args=(obj.pk, )))


3
유용한 답변에 감사드립니다. 코드 자체보다 나은 것은 없습니다. (또한 당신은 아마 url_name대신에 의미했을 것입니다 view_name)
Anupam

3
@Anupam reverse ()는 다음과 같이 정의됩니다 :def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
matias elgart

57

get_current_site사이트 앱 ( from django.contrib.sites.models import get_current_site)의 일부로 사용할 수도 있습니다 . 요청 객체를 가져 오며, SITE_IDrequest가이면 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
내 질문에 "사이트 모듈없이"라고 구체적으로 말한 것 같습니다. 이것이 DB에 충돌합니까?
mpen

1
사이트 모듈은 모듈 레벨 캐싱 (즉, 캐시 프레임 워크가 필요하지 않음)을 사용하여 사이트 오브젝트를 캐시하도록 작성되었으므로 웹 프로세스에서 사이트를 처음 검색 할 때만 DB에 도달해야합니다. 당신이하지 않으면 django.contrib.sites당신에 INSTALLED_APPS, 모든에서 DB에 충돌하지 않으며, (참조 요청 개체를 기반으로 정보를 제공 get_current_site )
DARB

1
그럼 당신은 +1을 가질 수 있지만 build_absolute_uri여전히 더 쉽고 깨끗한 솔루션처럼 보입니다.
mpen

1
전자 메일을 발송할 신호로 URL을 생성하려는 경우 완벽한 답변입니다.
Chris

2
https를 사용하면 작동하지 않습니다. 예, s를 추가 할 수는 있지만 https로 로컬로 개발합니까? https가 있지만 때로는 그렇지 않은 경우 항상 알고 있습니까?
tjati

55

액세스 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


7
이것은 HttpRequest 객체에 액세스 할 수 없을 때 정말 편리합니다. 예 : 작업, 신호 등
Arsham

6
이것을 사용하기 전에 사이트 프레임 워크 docs.djangoproject.com/en/dev/ref/contrib/sites/…를
madzohan

example.com을 다른 것으로 변경하려면 : Site.objects.all () [0]은 'example.com'을 반환하고 settings.py에 지정된 id = 1을 갖습니다. Site.objects.create (name = 'production', domain = 'prodsite.com')을 수행하고 settings.py에서 SITE_ID = 2를 설정하십시오. 이제 Site.objects.get_current (). domain은 'prodsite.com'을 반환합니다.
gek

당신은 설정할 수 있습니다 requestNone또는 전화 get_current_site(None).
Bobort

20

데이터베이스에 충돌하지 않으려면 설정을 사용하여 수행 할 수 있습니다. 그런 다음 컨텍스트 프로세서를 사용하여 모든 템플릿에 추가하십시오.

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

17

당신의 견해로는 다음과 같이하십시오.

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

14

django-fullurl

당신이 장고 템플릿에서이 작업을 수행하려는 경우, 나는 작은 PyPI 패키지를 출시했습니다 django-fullurl바꿀 수 있도록 url하고 static와 템플릿 태그 fullurlfullstatic같은를 :

{% load fullurl %}

Absolute URL is: {% fullurl "foo:bar" %}

Another absolute URL is: {% fullstatic "kitten.jpg" %}

이 배지는 자동으로 최신 상태를 유지해야합니다.

PyPI 트래비스 CI

보기에서는 물론 request.build_absolute_uri대신 사용할 수 있습니다 .


부끄러운 일이지만 2.0에서는 작동하지 않습니다. PR을 추진해야 할 수도 있습니다.
Steven Church

@StevenChurch 작동합니다. 아직 Django 2.0을 지원되는 것으로 표시하지 않았지만 기존 버전이 작동합니다.
Flimm

내 필요에 따라 Heroku에서 ENV를 페일 백으로 전달하여이 문제를 해결했습니다. 내 문제는 URL이 전자 메일 템플릿으로 전달되는 것입니다. 문제를 기억할 수 없지만 장고 변경으로 인해 작동하지 않았습니다.
Steven Church

@StevenChurch 전자 메일을 만들 때 문제 request는 도메인 이름을 가져올 객체 가 없다는 것입니다. 이 경우 sites데이터베이스에서 도메인 이름을 가져 오는 프레임 워크를 대신 사용해야 합니다. 참조 django-absoluteuri이 PyPI 패키지의 README의 "참조"절에서 언급.
Flimm

8

템플릿에서 다른 페이지에 대한 완전한 링크를 만들려면 다음을 사용하십시오.

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

request.META.HTTP_HOST는 호스트 이름을 제공하고 url은 상대 이름을 제공합니다. 그런 다음 템플리트 엔진은이를 완전한 URL로 연결합니다.


2
대답에는 프로토콜 ( http이 문맥에서)과 ://URL의 일부가 없으므로 완전한 url을 제공하지 않습니다 .
user272735

2
요청 객체에는 호스트가 있습니다. 직접 메타를 검사하지 마십시오 docs.djangoproject.com/en/1.8/ref/request-response/...
키트 Sunde

8

또 다른 방법. 당신이 사용할 수 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()가되지 않는 이유는 무엇입니까?
mpen


7

다음 코드를 시도하십시오.

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

경로와 쿼리 문자열없이 도메인을 제공합니다.
mpen

6

이것은 내 템플릿에서 나를 위해 일했습니다.

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

js 가져 오기 함수에 전달하려면 전체 URL이 필요했습니다. 도움이 되었기를 바랍니다.


5

나는 이것이 오래된 질문이라는 것을 안다. 그러나 나는 사람들이 여전히이 문제를 많이 겪고 있다고 생각합니다.

기본 Django 기능을 보완하는 몇 개의 라이브러리가 있습니다. 나는 몇 가지를 시도했다. 절대 URL을 역 참조 할 때 다음 라이브러리가 좋습니다.

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

도메인, 프로토콜 및 경로를 쉽게 구성 할 수 있기 때문에 내가 좋아하는 또 다른 하나는 다음과 같습니다.

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

이 라이브러리를 사용하면 템플릿에 원하는 것을 간단히 작성할 수 있습니다. 예 :

{{url_parts.domain}}

4

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
Ryan Amos

REST 프레임 워크를 사용하는 경우에만 사용할 수 있습니다. 잘 잡았습니다. 답변을 업데이트했습니다.
JohnG

네 감사합니다-이것은 django REST 프레임 워크
Apoorv Kansal

1

나는 그것을 얻었다 :

wsgiref.util.request_uri(request.META)

스키마, 호스트, 포트 경로 및 쿼리를 통해 전체 URI를 얻을 수 있습니다.


0

설정으로 사용 가능한 ABSOLUTE_URL_OVERRIDES도 있습니다

https://docs.djangoproject.com/en/2.1/ref/settings/#absolute-url-overrides

그러나 get_absolute_url ()을 재정의하므로 바람직하지 않습니다.

이를 위해 사이트 프레임 워크를 설치하거나 요청 객체에 의존하는 여기에 언급 된 다른 작업을 수행하는 대신이를 모델에 배치하는 것이 더 나은 해결책이라고 생각합니다.

settings.py에서 BASE_URL을 정의한 다음 models.py로 가져와 get_truly_absolute_url ()을 정의하는 추상 클래스를 작성하거나 이미 사용중인 클래스에 추가하십시오. 다음과 같이 간단 할 수 있습니다.

def get_truly_absolute_url(self):
    return BASE_URL + self.get_absolute_url()

서브 클래스로 이제 어디서나 사용할 수 있습니다.


0

다른 답변에서 언급 한 바와 같이, request.build_absolute_uri()당신은에 액세스 할 수있는 경우 완벽 request하고,sites 프레임 워크는 오랫동안 다른 URL이 서로 다른 데이터베이스를 가리 키만큼 큰 것입니다.

그러나 내 유스 케이스는 약간 다릅니다. 내 스테이징 서버와 프로덕션 서버는 동일한 데이터베이스에 액세스하지만 get_current_site둘 다 데이터베이스 에서 첫 번째 site를 리턴했습니다 . 이 문제를 해결하려면 일종의 환경 변수를 사용해야합니다. 1) 환경 변수 (예 :) os.environ.get('SITE_URL', 'localhost:8000')또는 2) SITE_ID다른 서버 및 다른 settings.py에 대해 다른 환경 변수를 사용할 수 있습니다 .

잘만되면 누군가 이것이 유용 할 것입니다!


0

성공 페이지의 절대 URI를 작성하려고했기 때문에이 스레드를 보았습니다. request.build_absolute_uri()현재 뷰에 대한 URI를 제공했지만 성공 뷰에 대한 URI를 얻으려면 다음을 사용했습니다.

request.build_absolute_uri (역 ( '성공 _보기 _ 이름'))



-5

다음을 사용할 수도 있습니다.

import socket
socket.gethostname()

이것은 나를 위해 잘 작동하고 있습니다.

그것이 어떻게 작동하는지 완전히 확신하지 못합니다. 나는 이것이 조금 낮은 수준이라고 생각하며 서버 호스트 이름을 반환 할 것입니다.이 이름은 사용자가 페이지에 도착하기 위해 사용하는 호스트 이름과 다를 수 있습니다.


그래 .. 문제를 지적했다. 호스트 이름은 반드시 도메인 이름과 같을 필요는 없습니다.
mpen

이것은 매우 다른 문제를 해결합니다. 위의 코드를 사용하여 URL을 생성하는 모든 사이트는 호스트 컴퓨터를 가리키는 모든 URL을 가지게되며 이는 실행중인 웹 사이트가 아닐 수 있습니다.
tbm

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.