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

당신은 설정할 수 있습니다 request에 None또는 전화 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와 템플릿 태그 fullurl와 fullstatic같은를 :

{% 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.