Sites 모듈없이https://example.com/some/path
Django에서 전체 / 절대 URL (예 : URL )을 얻으려면 어떻게 해야합니까? 그건 어리석은 일입니다 ... URL을 걸리기 위해 DB를 쿼리 할 필요가 없습니다!
와 함께 사용하고 싶습니다 reverse()
.
Sites 모듈없이https://example.com/some/path
Django에서 전체 / 절대 URL (예 : URL )을 얻으려면 어떻게 해야합니까? 그건 어리석은 일입니다 ... URL을 걸리기 위해 DB를 쿼리 할 필요가 없습니다!
와 함께 사용하고 싶습니다 reverse()
.
답변:
요청시 편리한 request.build_absolute_uri () 메소드를 사용 하고 상대 URL을 전달하면 전체 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 }}
함께 사용하려면 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
request가이면 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
, 모든에서 DB에 충돌하지 않으며, (참조 요청 개체를 기반으로 정보를 제공 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
당신이 장고 템플릿에서이 작업을 수행하려는 경우, 나는 작은 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
이 PyPI 패키지의 README의 "참조"절에서 언급.
템플릿에서 다른 페이지에 대한 완전한 링크를 만들려면 다음을 사용하십시오.
{{ 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.META
들어오는 사전을 검사하십시오 . 서버 이름과 서버 포트가 있다고 생각합니다.
이것은 내 템플릿에서 나를 위해 일했습니다.
{{ request.scheme }}:{{ request.META.HTTP_HOST }}{% url 'equipos:marca_filter' %}
js 가져 오기 함수에 전달하려면 전체 URL이 필요했습니다. 도움이 되었기를 바랍니다.
나는 이것이 오래된 질문이라는 것을 안다. 그러나 나는 사람들이 여전히이 문제를 많이 겪고 있다고 생각합니다.
기본 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 ()을 재정의하므로 바람직하지 않습니다.
이를 위해 사이트 프레임 워크를 설치하거나 요청 객체에 의존하는 여기에 언급 된 다른 작업을 수행하는 대신이를 모델에 배치하는 것이 더 나은 해결책이라고 생각합니다.
settings.py에서 BASE_URL을 정의한 다음 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
다른 서버 및 다른 settings.py에 대해 다른 환경 변수를 사용할 수 있습니다 .
잘만되면 누군가 이것이 유용 할 것입니다!
다음을 사용할 수도 있습니다.
import socket
socket.gethostname()
이것은 나를 위해 잘 작동하고 있습니다.
그것이 어떻게 작동하는지 완전히 확신하지 못합니다. 나는 이것이 조금 낮은 수준이라고 생각하며 서버 호스트 이름을 반환 할 것입니다.이 이름은 사용자가 페이지에 도착하기 위해 사용하는 호스트 이름과 다를 수 있습니다.