programing

장고 템플릿 내에서 내 사이트의 도메인 이름을 가져오는 방법은 무엇입니까?

yellowcard 2023. 5. 20. 10:37
반응형

장고 템플릿 내에서 내 사이트의 도메인 이름을 가져오는 방법은 무엇입니까?

장고 템플릿 내에서 현재 사이트의 도메인 이름을 가져오려면 어떻게 해야 합니까?태그와 필터를 찾아봤지만 아무것도 없었습니다.

실제 HTTP Host 헤더를 원하는 경우, @Phsiao의 답변에 대한 Daniel Roseman의 코멘트를 참조하십시오.다른 대안은 기여를 사용하는 것입니다.사이트 프레임워크를 사용하면 데이터베이스에서 사이트에 대한 표준 도메인 이름을 설정할 수 있습니다(요청 도메인을 적절한 SITE_ID로 설정 파일에 매핑하는 것은 웹 서버 설정을 통해 직접 수행해야 하는 작업입니다).이 경우, 다음을 찾으실 수 있습니다.

from django.contrib.sites.models import Site

current_site = Site.objects.get_current()
current_site.domain

current_site 객체를 사용하려면 직접 템플릿 컨텍스트에 넣어야 합니다.어디서나 사용하는 경우 템플릿 컨텍스트 프로세서로 패키지화할 수 있습니다.

저는 그 방법을 발견했습니다.

요청 컨텍스트에 액세스하는 것이 필요하다고 생각합니다. 요청 컨텍스트를 참조하십시오.

Carl Meyer를 보완하여 다음과 같은 컨텍스트 프로세서를 만들 수 있습니다.

module.sys_processors.파이의

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",
    ....
 )

컨텍스트 인스턴스를 반환하는 템플릿 URL 사이트는 {{SITE_URL}}입니다.

컨텍스트 프로세서에서 하위 도메인 또는 SSL을 처리하려면 자신의 루틴을 작성할 수 있습니다.

저는 이 질문이 오래된 것이라는 것을 알지만, 저는 현재의 영역을 얻는 비단결적인 방법을 찾다가 우연히 발견했습니다.

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

렌더를 사용하는 경우와 같은 요청 컨텍스트를 사용해야 합니다.

마 ㅠㅠㅠㅠrequest.META['HTTP_HOST']운영 환경: 해당 정보는 브라우저에서 제공됩니다. @CarlMeyer의인 @CarlMeyer를하세요.

{{ request.get_host }}는 HTTP 호스트 할 때 HTTP 헤더 공격으로부터 .ALLOWED_HOSTS설정(장고 1.4.4에 추가됨).

:{{ request.META.HTTP_HOST }}에는 동일한 보호 기능이 없습니다.문서 참조:

Allowed_호스트

이 Django 사이트에서 사용할 수 있는 호스트/도메인 이름을 나타내는 문자열 목록입니다.이는 안전해 보이는 많은 웹 서버 구성에서도 가능한 HTTP 호스트 헤더 공격을 방지하기 위한 보안 조치입니다.

에 약에만.Host 머또글 (는리또))X-Forwarded-Host한다면USE_X_FORWARDED_HOSTenabled)는 이. 이 목록의 값은 다음과 같습니다.django.http.HttpRequest.get_host()▁raise니를 올릴 입니다.SuspiciousOperation.

검사는 " 다은적다니용됩만통해서이음을검증▁applies다▁via▁this니▁onlyation▁valid"를 통해서만 적용됩니다.get_host()에서 호스트 헤더에 request.META이 보안 보호를 무시하고 있습니다.


사에대는서를 하는 것에 request당신의 템플릿에서 템플릿 렌더링 함수 호출은 장고 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 %}

제가 사용하는 콘텍스트 프로세서의 변형은 다음과 같습니다.

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 }}현재 도메인 이름을 가져옵니다.

edit: 프로토콜 전환도 지원하려면 다음을 사용합니다.

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)),
    }

사용자 지정 템플릿 태그를 사용합니다.예를 들어, <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 %}

"요청" 컨텍스트 프로세서를 사용하고 Django 사이트 프레임워크를 사용 중이며 사이트 미들웨어를 설치한 경우(예: 설정에 다음이 포함됨):

INSTALLED_APPS = [
    ...
    "django.contrib.sites",
    ...
]

MIDDLEWARE = [
    ...
     "django.contrib.sites.middleware.CurrentSiteMiddleware",
    ...
]

그러면 당신은 그것을 갖게 될 것입니다.request할 수 있으며 인 오브젝트에 됩니다.Site 로의요에대여하청▁as여▁the▁for▁request하대.request.site그런 다음 다음을 사용하여 템플릿의 도메인을 검색할 수 있습니다.

    {{request.site.domain}}

사이트 이름에 다음이 포함됩니다.

    {{request.site.name}}

사용자 팬치코어의 답변과 유사하게, 이것은 제가 매우 간단한 웹사이트에서 한 것입니다.몇 가지 변수를 제공하고 템플릿에서 사용할 수 있도록 합니다.

SITE_URL다음과 같은 가치가 있을 것입니다.example.com
SITE_PROTOCOL다음과 같은 가치가 있을 것입니다.http또는https
SITE_PROTOCOL_URL다음과 같은 가치가 있을 것입니다.http://example.com또는https://example.com
SITE_PROTOCOL_RELATIVE_URL다음과 같은 가치가 있을 것입니다.//example.com.

module/module_processors.파이의

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
    }

설정.파이의

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    "module.context_processors.site",
    ....
 )

SITE_URL = 'example.com'

그런 다음 템플릿에서 다음과 같이 사용합니다.{{ SITE_URL }},{{ SITE_PROTOCOL }},{{ SITE_PROTOCOL_URL }}그리고.{{ SITE_PROTOCOL_RELATIVE_URL }}

사용할 수 있습니다.

기본적으로 전체 경로가 반환됩니다.

그러나 다음과 같은 매개 변수를 전달하면 다음과 같습니다.

request.build_absolute_uri('/')

그러면 도메인 이름이 반환됩니다.

Django 템플릿에서 다음 작업을 수행할 수 있습니다.

<a href="{{ request.scheme }}://{{ request.META.HTTP_HOST }}{{ request.path }}?{{ request.GET.urlencode }}" >link</a>

이 접근법은 어떻습니까?나한테 효과가 있어요.장고 등록에도 사용됩니다.

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)

저는 우리가 원하는 것이 기존의 것에 대한 대안이라고 생각합니다.url태그, 그래서 새로운 태그를 작성했습니다.

from django.template import Library
from django.urls     import reverse

@register.simple_tag(takes_context = True)
def fullURL(context, name, *args, **kwargs):
    request = context['request']
    return f'{request.scheme}://{request.get_host()}{reverse(name, args = args, kwargs = kwargs)}'

그리고 당신의 템플릿에서 이것을 가질 수 있습니다...

{% extends "myapp/email/email_base.html" %}

{% load mytags %} {# Replace mytags with whatever the name of your custom tags calss is. #}

{% block content %}
<p>You can use <a href="{% fullURL 'signup' %}">this link</a> to get started with your account. We look forward to seeing you soon!</p>
{% endblock content %}

그런 다음 이것을 생성할 때, 당신은 단지 통과하는 것을 기억하면 됩니다.request에.context그런 식으로...

from django.template.loader import render_to_string

def sendEmail(subject, to, template, **context):
    html = render_to_string(f'myapp/email/{template}.html', context | {'subject': subject})
    # ... and so on with the rest of my function for sending email...

@furins 응답에서 언급했듯이 프록시 서버에 문제가 있을 수 있습니다.Apache 및 uWSGI를 사용할 때 직접 발견했습니다.request.get_host또는request.build_absolute_uri프록시 호스트를 반환합니다(127.0.0.1:9191…).

그러나 다른 사용자가 이 문제를 해결하기 위한 가이드를 게시했습니다.

https://ubuntu.com/blog/django-behind-a-proxy-fixing-absolute-urls

이것은 비교적 오래된 답변이지만, 여전히 장고 3.2와 파이썬 3.9와 관련이 있습니다.

나중에 답이 사라질 경우를 대비해 그 요지는 다음과 같습니다.

설정.파이의

# Setup support for proxy headers
USE_X_FORWARDED_HOST = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

apache.conf

<VirtualHost *:443>
    ...
    RequestHeader set X-Forwarded-Proto 'https' env=HTTPS

    ProxyPass / http://10.0.0.3/
    ProxyPassReverse / http://10.0.0.3/
    ...
</VirtualHost>

이 설정을 사용할 경우request.get_host그리고.request.build_absolute_uri프록시 호스트가 아닌 클라이언트 요청 호스트를 참조합니다.

다음은 전체 URL과 URL의 일부를 가져올 수 있습니다.

def myview(request):
    request.build_absolute_uri()
    # http://localhost:8000/admin/store/product/

    request.build_absolute_uri('/')
    # http://localhost:8000/

    request.build_absolute_uri('/')[:-1]
    # http://localhost:8000

    request.scheme
    # http

    request.META['HTTP_HOST']
    # localhost:8000

    request.path    
    # /admin/store/product/
from django.contrib.sites.models import Site
if Site._meta.installed:
    site = Site.objects.get_current()
else:
    site = RequestSite(request)

사용할 수 있습니다.{{ protocol }}://{{ domain }}템플릿에서 도메인 이름을 가져옵니다.

언급URL : https://stackoverflow.com/questions/1451138/how-to-get-the-domain-name-of-my-site-within-a-django-template

반응형