Django 템플릿 내에서 현재 사이트의 도메인 이름을 어떻게 얻습니까? 태그와 필터를 보려고했지만 아무것도 없습니다.
Django 템플릿 내에서 현재 사이트의 도메인 이름을 어떻게 얻습니까? 태그와 필터를 보려고했지만 아무것도 없습니다.
답변:
원하는 것은 요청 컨텍스트에 액세스하는 것입니다. RequestContext를 참조하십시오.
Host:
헤더를 스푸핑하고 페이지의 어딘가에서 스푸핑 된 도메인으로 응답을 받으면 어떻게 보안 허점을 만들 수 있습니까? 생성 된 HTML을 가져 와서 자신의 브라우저에 공급하기 전에 자신을 수정하는 사용자와 어떻게 다른지 알 수 없습니다.
실제 HTTP 호스트 헤더를 원하면 @Phsiao의 답변에 대한 Daniel Roseman의 의견을 참조하십시오. 다른 대안은 contrib.sites 프레임 워크를 사용하는 경우 데이터베이스의 사이트에 대한 표준 도메인 이름을 설정할 수 있습니다 (요청 도메인을 올바른 SITE_ID를 사용하여 설정 파일로 매핑하는 것은 사용자가 직접 수행해야하는 것임) 웹 서버 설정). 이 경우 찾고 있습니다 :
from django.contrib.sites.models import Site
current_site = Site.objects.get_current()
current_site.domain
current_site 객체를 사용하려면 템플릿 컨텍스트에 current_site 객체를 직접 넣어야합니다. 모든 곳에서 사용하는 경우 템플릿 컨텍스트 프로세서로 패키지화 할 수 있습니다.
SITE_ID
설정이 id
사이트 앱의 현재 사이트 속성 과 같은지 확인합니다 ( id
사이트 관리자 패널에서 찾을 수 있음 ). 를 호출 get_current
하면 Django가 사용자를 가져 와서 해당 ID를 가진 객체를 데이터베이스에서 SITE_ID
반환 Site
합니다.
print("get_current_site: ", get_current_site(request)) print("absolute uri: ", request.build_absolute_uri()) print("HTTP_HOST: ", request.META['HTTP_HOST']) get_current_site: localhost:8001 absolute uri: http://localhost:8001/... HTTP_HOST: localhost:8001
나는 그 {{ request.get_host }}
방법을 발견했다 .
HTTP_X_FORWARDED_HOST
HTTP 헤더 를 고려하기 때문에 HTTP 프록시 또는로드 밸런서를 통해 호스트에 도달하면 더 완벽합니다 .
request.build_absolute_uri
( docs.djangoproject.com/en/dev/ref/request-response/… )
Carl Meyer를 보완하면 다음과 같은 컨텍스트 프로세서를 만들 수 있습니다.
from django.conf import settings
def site(request):
return {'SITE_URL': settings.SITE_URL}
SITE_URL = 'http://google.com' # this will reduce the Sites framework db call.
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
컨텍스트 프로세서에서 하위 도메인 또는 SSL을 처리하려는 경우 자체 루틴을 작성할 수 있습니다.
내가 사용하는 컨텍스트 프로세서의 변형은 다음과 같습니다.
from django.contrib.sites.shortcuts import get_current_site
from django.utils.functional import SimpleLazyObject
def site(request):
return {
'site': SimpleLazyObject(lambda: get_current_site(request)),
}
SimpleLazyObject
래퍼 템플릿이 실제로 사용하면 DB 호출에만 발생 확인합니다site
개체를. 관리 페이지에서 쿼리가 제거됩니다. 또한 결과를 캐시합니다.
설정에 포함하십시오.
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
템플릿 {{ site.domain }}
에서 현재 도메인 이름을 얻는 데 사용할 수 있습니다 .
편집 : 프로토콜 전환도 지원 하려면 다음 을 사용하십시오.
def site(request):
site = SimpleLazyObject(lambda: get_current_site(request))
protocol = 'https' if request.is_secure() else 'http'
return {
'site': site,
'site_root': SimpleLazyObject(lambda: "{0}://{1}".format(protocol, site.domain)),
}
SimpleLazyObject
어쨌든 '사이트'에 액세스하는 것이 없으면 람다가 호출 되지 않으므로 여기에서 사용할 필요가 없습니다 .
SimpleLazyObject
각각 RequestContext
이를 호출 get_current_site()
하여 SQL 쿼리를 실행합니다. 랩퍼는 변수가 실제로 템플리트에서 사용될 때만 평가되도록합니다.
SimpleLazyObject
이후 정말 필요하지 않은 기능의 재평가 방지하기 위해이 Site
객체가 캐시됩니다.
from django.contrib.sites.shortcuts import get_current_site
나는이 질문이 오래되었다는 것을 알고 있지만 현재 도메인을 얻는 파이썬적인 방법을 찾고 있습니다.
def myview(request):
domain = request.build_absolute_uri('/')[:-1]
# that will build the complete domain: http://foobar.com
빠르고 간단하지만 생산에는 좋지 않습니다.
(보기에서)
request.scheme # http or https
request.META['HTTP_HOST'] # example.com
request.path # /some/content/1/
(템플릿에서)
{{ request.scheme }} :// {{ request.META.HTTP_HOST }} {{ request.path }}
render를 사용하는 경우 RequestContext 를 사용해야합니다 .
request.META['HTTP_HOST']
프로덕션을 신뢰하지 마십시오 . 해당 정보는 브라우저에서 제공됩니다. 대신 @CarlMeyer의 답변을 사용하십시오.
request.scheme
. 아마도 최신 버전의 장고에서만 사용할 수 있습니다.
request.scheme
가 Django 1.7에 추가되었습니다.
{{ request.get_host }}
ALLOWED_HOSTS
설정 과 함께 사용될 때 HTTP 호스트 헤더 공격으로부터 보호해야 합니다 (Django 1.4.4에 추가됨).
참고 {{ request.META.HTTP_HOST }}
동일한 보호가 없습니다. 문서를 참조하십시오 :
ALLOWED_HOSTS
이 장고 사이트가 제공 할 수있는 호스트 / 도메인 이름을 나타내는 문자열 목록입니다. 이것은 HTTP 호스트 헤더 공격 을 방지하기위한 보안 조치입니다. 웹 서버 , 많은 안전한 웹 서버 구성에서도 가능합니다.
...
Host
헤더 (또는 활성화 된X-Forwarded-Host
경우USE_X_FORWARDED_HOST
)가이 목록의 값과 일치하지 않으면django.http.HttpRequest.get_host()
메서드가 발생SuspiciousOperation
합니다....이 검증은 다음을 통해서만 적용됩니다
get_host()
. 코드가 직접 호스트 헤더에 액세스하는request.META
경우이 보안 보호를 우회합니다.
request
템플릿에서 를 사용하면 Django 1.8에서 템플릿 렌더링 함수 호출이 변경되어 더 이상 처리 할 필요가 없습니다.RequestContext
직접 할 .
바로 가기 기능을 사용하여 뷰의 템플릿을 렌더링하는 방법은 다음과 같습니다 render()
.
from django.shortcuts import render
def my_view(request):
...
return render(request, 'my_template.html', context)
이메일을위한 템플릿을 렌더링하는 방법은 다음과 같습니다. IMO는 호스트 값을 원하는 가장 일반적인 경우입니다.
from django.template.loader import render_to_string
def my_view(request):
...
email_body = render_to_string(
'my_template.txt', context, request=request)
다음은 이메일 템플릿에 전체 URL을 추가하는 예입니다. request.scheme는 얻어야한다 http
또는 https
당신이 사용중인에 따라 :
Thanks for registering! Here's your activation link:
{{ request.scheme }}://{{ request.get_host }}{% url 'registration_activate' activation_key %}
맞춤 템플릿 태그를 사용합니다. 예를 들어 <your_app>/templatetags/site.py
다음과 같이 추가하십시오 .
# -*- coding: utf-8 -*-
from django import template
from django.contrib.sites.models import Site
register = template.Library()
@register.simple_tag
def current_domain():
return 'http://%s' % Site.objects.get_current().domain
다음과 같은 템플릿에서 사용하십시오.
{% load site %}
{% current_domain %}
get_current
문서화 된 방법입니다. docs.djangoproject.com/en/dev/ref/contrib/sites/…
'http://%s'
https
연결시 문제가 될 수 있습니다 . 이 경우 체계가 역동적이지 않습니다.
사용자 panchicore의 답변과 유사하게 이것은 매우 간단한 웹 사이트에서 한 일입니다. 몇 가지 변수를 제공하고 템플릿에서 사용할 수있게합니다.
SITE_URL
같은 값 example.com
SITE_PROTOCOL
을 보유 http
하거나 https
SITE_PROTOCOL_URL
같은 값 을 보유 http://example.com
하거나https://example.com
SITE_PROTOCOL_RELATIVE_URL
//example.com
.
module / context_processors.py
from django.conf import settings
def site(request):
SITE_PROTOCOL_RELATIVE_URL = '//' + settings.SITE_URL
SITE_PROTOCOL = 'http'
if request.is_secure():
SITE_PROTOCOL = 'https'
SITE_PROTOCOL_URL = SITE_PROTOCOL + '://' + settings.SITE_URL
return {
'SITE_URL': settings.SITE_URL,
'SITE_PROTOCOL': SITE_PROTOCOL,
'SITE_PROTOCOL_URL': SITE_PROTOCOL_URL,
'SITE_PROTOCOL_RELATIVE_URL': SITE_PROTOCOL_RELATIVE_URL
}
settings.py
TEMPLATE_CONTEXT_PROCESSORS = (
...
"module.context_processors.site",
....
)
SITE_URL = 'example.com'
그런 다음, 템플릿,로 사용 {{ SITE_URL }}
, {{ SITE_PROTOCOL }}
, {{ SITE_PROTOCOL_URL }}
및{{ SITE_PROTOCOL_RELATIVE_URL }}
Django 템플릿에서 다음을 수행 할 수 있습니다.
<a href="{{ request.scheme }}://{{ request.META.HTTP_HOST }}{{ request.path }}?{{ request.GET.urlencode }}" >link</a>
django.template.context_processors.request
또한 [이 어떻게에 도움] ( simpleisbetterthancomplex.com/tips/2016/07/20/... )
당신이 사용하는 경우 "요청"상황에 맞는 프로세서를 하고 사용하는 장고 사이트 프레임 워크를 하고있는 사이트 미들웨어 설치 (즉, 설정은 다음을 포함한다) :
INSTALLED_APPS = [
...
"django.contrib.sites",
...
]
MIDDLEWARE = [
...
"django.contrib.sites.middleware.CurrentSiteMiddleware",
...
]
TEMPLATES = [
{
...
"OPTIONS": {
"context_processors": [
...
"django.template.context_processors.request",
...
]
}
}
]
... 그러면 request
템플릿 에서 객체를 사용할 수 있으며 현재에 대한 참조가 포함됩니다Site
요청 대한 됩니다 request.site
. 그런 다음 다음을 사용하여 템플릿에서 도메인을 검색 할 수 있습니다.
{{request.site.domain}}
이 방법은 어떻습니까? 나를 위해 작동합니다. django-registration 에서도 사용됩니다 .
def get_request_root_url(self):
scheme = 'https' if self.request.is_secure() else 'http'
site = get_current_site(self.request)
return '%s://%s' % (scheme, site)
localhost
얻을 수 있습니다 https
( http://127.0.0.1
유효하지 않습니다 https://127.0.0.1
). 따라서 개발 중에는 이상적이지 않습니다.
당신이 사용할 수있는 {{ protocol }}://{{ domain }}
도메인 이름을 얻을 수 있도록 템플릿에서.
request.META['HTTP_HOST']
도메인을 제공합니다. 템플릿에서는입니다{{ request.META.HTTP_HOST }}
.