>백엔드 개발 >파이썬 튜토리얼 >Django 통합 서브프레임워크

Django 통합 서브프레임워크

黄舟
黄舟원래의
2017-01-17 14:05:281213검색

Python에는 많은 장점이 있으며, 그 중 하나는 "즉시 사용 가능한" 원칙입니다. Python을 설치할 때 다수의 표준 소프트웨어 패키지가 동시에 설치되므로 별도의 작업을 하지 않고도 즉시 사용할 수 있습니다. 직접 다운로드하세요. Django도 이 원칙을 따르며 자체 표준 라이브러리도 포함합니다. 이 장에서는 이러한 통합 하위 프레임워크에 대해 설명합니다.


Django 표준 라이브러리


Django의 표준 라이브러리는 django.contrib 패키지에 있습니다. 각 하위 패키지는 추가 기능이 포함된 독립적인 패키지입니다. 일반적으로 서로 반드시 관련되어 있는 것은 아니지만 일부 django.contrib 하위 패키지는 다른 패키지에 종속될 수 있습니다.


django.contrib의 함수 유형에 대한 필수 요구사항은 없습니다. 이러한 패키지 중 일부는 모델과 함께 제공되지만(따라서 데이터베이스에 해당 테이블을 설치해야 함) 다른 패키지는 독립 실행형 미들웨어와 템플릿 태그로 구성됩니다.


django.contrib 개발 패키지의 공통 기능은 django.contrib 개발 패키지 전체를 삭제하더라도
의 기본 기능을 그대로 사용할 수 있다는 점입니다. 어떤 문제도 발생하지 않은 Django입니다. Django 개발자가 프레임워크에 새 기능을 추가할 때 django.contrib에 새 기능을 넣을지 여부를 결정할 때 이 원칙을 엄격하게 따릅니다.


django.contrib은 다음 개발 패키지로 구성됩니다.


§ admin: 자동화된 사이트 관리 도구. Django 관리 사이트


§ auth: Django의 사용자 인증 프레임워크를 확인하세요. 세션, 사용자 및 등록을 확인하세요


§ 댓글: 현재 이 애플리케이션은 집중적으로 개발 중이므로 이 애플리케이션이 게시되는 시점에는 제공될 수 없습니다. 이 애플리케이션에 대한 전체 설명과 자세한 내용은 Django 공식 웹사이트에서 확인할 수 있습니다.


§ contenttypes: 이것은 문서 유형 후크에 대한 프레임워크이며, 각 Django 모듈은 다음과 같습니다. 독립형 문서 유형으로 설치됩니다. 이 프레임워크는 주로 Django 내에서 다른 애플리케이션에 의해 사용되며 주로 고급 Django 개발자를 위한 것입니다. 소스 코드를 읽으면 이 프레임워크에 대해 자세히 알아볼 수 있습니다. 소스 코드는 django/contrib/contenttypes/에 있습니다.


§ csrf: 이 모듈은 방지하는 데 사용됩니다. CSRF(교차 사이트 요청 위조). "CSRF 방어"라는 제목의 뒷부분을 참조하세요.


§ 플랫페이지: 데이터베이스의 단일 HTML 콘텐츠를 관리하는 모듈입니다. 아래의 "플랫페이지" 섹션을 참조하세요.


§ humanize: 데이터의 인간화를 높이는 데 사용되는 일련의 Django
모듈 필터입니다.


§ 마크업: 일부 일반적인 마크업 언어를 구현하는 데 사용되는 일련의 Django
템플릿 필터입니다.


§ 리디렉션: 리디렉션을 관리하는 데 사용되는 프레임워크입니다.


§ 세션: Django의 세션 프레임워크, 세션, 사용자 및 등록을 참조하세요.


§ 사이트맵: 사이트 맵용 XML
파일을 생성하기 위한 프레임워크입니다. HTML이 아닌 콘텐츠를 출력하는 Django를 참조하세요.


§ 사이트: 동일한 데이터베이스 및 Django 설치 내에서 여러 웹사이트를 관리할 수 있는 프레임워크입니다.


§ 신디케이션: RSS
및 Atom을 사용하여 신디케이션 피드를 생성하기 위한 프레임워크입니다. HTML이 아닌 콘텐츠를 출력하는 Django를 참조하세요.


이 장에서는 이전에 소개되지 않았던 django.contrib 개발 패키지의 내용을 자세히 설명합니다.


다중 사이트


Django의 다중 사이트 시스템은 하나의 데이터베이스 하에서 여러 웹사이트를 운영할 수 있게 해주는 범용 프레임워크입니다. 동일한 Django 프로젝트. 이는 다소 이해하기 어려울 수 있는 추상적인 개념이므로 유용하게 사용할 수 있는 몇 가지 실제 시나리오부터 시작하겠습니다.


시나리오 1: 여러 사이트의 데이터 재사용




1장에서 말했듯이 Django로 구축된 LJWorld.com 및 Lawrance.com
웹사이트는 동일한 언론사인 The Lawrence Journal in Lawrence, Kansas World Newspapers에서 관리합니다. LJWorld.com은 뉴스에 중점을 두고 있고,
Lawrence.com은 지역 엔터테인먼트에 중점을 두고 있습니다. 그러나 때로는 편집자가 두 개의 웹사이트에 기사를 게시해야 할 수도 있습니다.


이 문제에 대한 막다른 해결책은 각 사이트마다 다른 데이터베이스를 사용한 다음 사이트 관리자에게 동일한 기사를 두 번(LJWorld에 한 번) 게시하도록 요청하는 것입니다. .com과 또 다른 시간에는 Lawrence.com이 있습니다. 그러나 이는 사이트 관리자에게 비효율적이며 동일한 기사의 여러 복사본을 데이터베이스에 보관하는 것은 중복됩니다.


더 나은 솔루션이 있을까요? 두 웹사이트는 동일한 기사 데이터베이스를 사용하고 다대다 관계를 사용하여 각 기사를 하나 이상의 사이트와 연결합니다. Django 사이트 프레임워크는 어떤 기사가 연결될 수 있는지 기록하는 데이터베이스를 제공합니다. 데이터를 하나 이상의 사이트와 연결하는 후크입니다.


시나리오 2: 웹사이트 이름/도메인을 고유한 위치에 저장


LJWorld.com 및 Lawrence .com 이메일 알림 기능이 있어 독자가 등록 후 뉴스가 나오면 즉시 알림을 받을 수 있습니다. 이는 완벽한 메커니즘입니다. 독자가 등록 양식을 제출하면 즉시 "등록해 주셔서 감사합니다" 이메일을 받게 됩니다.




이 등록 프로세스의 코드를 두 번 구현하는 것은 분명히 비효율적이고 중복되므로 두 사이트는 백그라운드에서 동일한 코드를 사용합니다. 하지만 가입에 대한 감사 알림은 두 웹사이트에서 서로 달라야 합니다. Site 개체를 사용하면 현재 사이트 이름(예: 'LJWorld.com')과 도메인(예: 'www.ljworld.com')을 사용하여 감사 알림을 추출할 수 있습니다.


Django의 다중 사이트 프레임워크는 Django 프로젝트에 있는 각 사이트의 이름과 도메인을 저장할 수 있는 장소를 제공합니다. 즉, 이러한 값을 동일한 방식으로 재사용할 수 있습니다.


다중 사이트 프레임워크 사용 방법


다중 사이트 프레임워크는 프레임워크라기보다는 그것은 일련의 관례입니다. 모든 것은 두 가지 간단한 개념을 기반으로 합니다:


§ django.contrib.sites에 있는 사이트 모델에는 도메인과 이름이라는 두 가지 필드가 있습니다.


§ SITE_ID 설정은 특정 구성 파일과 연결된 사이트 개체의 데이터베이스 ID를 지정합니다.


이 두 가지 개념을 어떻게 사용하는지는 여러분에게 달려 있지만 Django는 몇 가지 간단한 규칙을 사용하여 자동으로 이를 수행합니다.


다중 사이트 애플리케이션을 설치하려면 다음 단계를 수행하세요.


1. 'django.contrib'을 변경합니다. .sites 'INSTALLED_APPS에 추가합니다.


2.manage.py syncdb 명령을 실행하여 django_site 테이블을 데이터베이스에 설치합니다.


3. Django 관리 백엔드 또는 Python API를 통해 하나 이상의
'사이트' 개체를 추가합니다. Django
프로젝트에서 지원하는 각 사이트(또는 도메인)에 대한 사이트 개체를 만듭니다.


4. 각 설정 파일에서 SITE_ID 변수를 정의합니다. 이 변수의 값은 구성 파일에서 지원하는 사이트의 사이트 개체에 대한 데이터베이스
ID여야 합니다.


다중 사이트 프레임워크의 기능


다음 섹션에서는 다중 사이트 프레임워크로 수행할 수 있는 몇 가지 작업을 설명합니다. -사이트 프레임워크 작업.


여러 사이트에서 데이터 재사용


시나리오 1에서 설명했듯이 여러 사이트에서 데이터 재사용 사이트의 경우 모델에서 사이트에 대한 다대다 필드만 추가하면 됩니다. 예:

from django.db import models
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(maxlength=200)
# ...
sites = models.ManyToManyField(Site)

이는 데이터베이스의 여러 사이트에 대해 기사 연결 작업을 수행하는 기본 단계입니다. 이 기술을 사용하면 여러 사이트에서 동일한 Django 뷰 코드 조각을 재사용할 수 있습니다. 기사 모델 예제를 계속하면 가능한 기사_세부 사항 보기는 다음과 같습니다.

from django.conf import settings
def article_detail(request, article_id):
try:
a = Article.objects.get(id=article_id, sites__id=settings.SITE_ID)
except Article.DoesNotExist:
raise Http404

# ...

이 보기 방법은 SITE_ID에 의해 설정된 값을 기반으로 기사 사이트를 동적으로 확인하므로 재사용이 가능합니다. .


예를 들어 LJWorld.coms 설정 파일의 SITE_ID는 1로 설정되고
Lawrence.coms 설정 파일의 SITE_ID는 2로 설정됩니다. LJWorld.coms가 활성화된 동안 이 보기를 호출하면
LJWorld.com이 포함된 사이트 목록의 기사로 검색이 제한됩니다.


콘텐츠를 단일 사이트와 연결


마찬가지로 다대일에서도 외래 키를 사용할 수 있습니다. 관계 모델을 사이트 모델에 연결합니다.


예를 들어 특정 기사가 한 사이트에만 표시될 수 있는 경우 다음 모델을 사용할 수 있습니다.

from django.db import models
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(maxlength=200)
# ...
site = models.ForeignKey(Site)

이전과 동일합니다. 하나는 섹션에 소개된 것만큼 유용합니다.


뷰에서 현재 사이트 연결


Django 뷰에서 다중 사이트 프레임워크를 사용하여 내부적으로 , you 호출 사이트에 따라 보기가 다른 작업을 수행하도록 할 수 있습니다. 예를 들면 다음과 같습니다.

from django.conf import settings
def my_view(request):
if settings.SITE_ID == 3:
# Do something.
else:
# Do something else.

물론 사이트 ID를 그렇게 하드코딩하는 것은 보기 흉합니다. 이를 수행하는 약간 더 간단한 방법은 현재 사이트 도메인을 보는 것입니다:

from django.conf import settings
from django.contrib.sites.models import Site
def my_view(request):
current_site = Site.objects.get(id=settings.SITE_ID)
if current_site.domain == 'foo.com':
# Do something
else:
# Do something else.

사이트 개체에서 settings.SITE_ID 값을 얻는 것이 일반적이므로 사이트 모델 관리자
(Site.objects) get_current( ) 메소드가 있습니다. 다음 예는 이전 예와 동일합니다.


from django.contrib.sites.models import Site
def my_view(request):
current_site = Site.objects.get_current()
if current_site.domain == 'foo.com':
# Do something
else:
# Do something else.

참고


이 마지막 예에서는 django.conf.settings를 가져올 필요는 없습니다.


렌더링을 위한 현재 도메인 가져오기


시나리오 2에서 설명한 대로 사이트 이름과 도메인 이름을 저장하기 위해 DRY(Dont Repeat Yourself) 방법(사이트 이름과 도메인 이름을 한 위치에 저장)을 사용하는 경우 현재 사이트 개체의 이름과 도메인만 참조하면 됩니다. 예:

from django.contrib.sites.models import Site
from django.core.mail import send_mail
def register_for_newsletter(request):
# Check form values, etc., and subscribe the user.
# ...
current_site = Site.objects.get_current()
send_mail('Thanks for subscribing to %s alerts' % current_site.name,
'Thanks for your subscription. We appreciate it./n/n-The %s team.' % current_site.name,
'editor@%s' % current_site.domain,
[user_email])
# ...

LJWorld.com 및 Lawrence.com
을 계속해서 논의하고 있는 Lawrence.com
의 사례에서 이메일 제목은 "Lawrence에 가입해 주셔서 감사합니다"입니다. .com 알림 이메일입니다."
LJWorld.com에서 이메일 제목은 "LJWorld.com 알림 이메일에 가입해주셔서 감사합니다"입니다. 이 사이트 관련 동작은 이메일 메시지 제목에도 적용됩니다.


이를 수행하는 더 유연한(그러나 더 무거운) 방법은 Django의 템플릿 시스템을 사용하는 것입니다. Lawrence.com과
LJWorld.com이 각각 서로 다른 템플릿 디렉터리(TEMPLATE_DIRS)를 가지고 있다고 가정하면 다음과 같이 작업을 템플릿 시스템으로 쉽게 전송할 수 있습니다.

from django.core.mail import send_mail
from django.template import loader, Context
def register_for_newsletter(request):
# Check form values, etc., and subscribe the user.
# ...
subject = loader.get_template('alerts/subject.txt').render(Context({}))
message = loader.get_template('alerts/message.txt').render(Context({}))
send_mail(subject, message, 'do-not-reply@example.com', [user_email])
# ...


이 예에서는 LJWorld.com과 Lawrence.com
의 템플릿 디렉터리 모두에 subject.txt 및 message.txt 템플릿을 생성해야 합니다. 앞서 언급한 것처럼 이 접근 방식은 유연성이 더 높지만 복잡성도 더 높습니다.


Site 개체를 최대한 많이 사용하는 것은 불필요하고 복잡하고 중복되는 작업을 줄이는 좋은 방법입니다.


현재 도메인의 전체 URL 가져오기


Django 的get_absolute_url()约定对与获取不带域名的对象 URL非常理想,但在某些情形下,你可能想显示某个对象带有http://和域名以及所有部分的完整
URL。要完成此工作,你可以使用多站点框架。下面是个简单的例子:

>>> from django.contrib.sites.models import Site
>>> obj = MyModel.objects.get(id=3)
>>> obj.get_absolute_url()
'/mymodel/objects/3/'
>>> Site.objects.get_current().domain
'example.com'
>>> 'http://%s%s' % (Site.objects.get_current().domain, obj.get_absolute_url())

'http://example.com/mymodel/objects/3/'

当前站点管理器


如果站点在你的应用中扮演很重要的角色,请考虑在你的模型中使用方便的CurrentSiteManager。这是一个模型管理器(见附录B),它会自动过滤使其只包含与当前站点相关联的对象。


通过显示地将CurrentSiteManager加入模型中以使用它。例如:


from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(maxlength=100)
pub_date = models.DateField()
site = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager()

通过该模型,``Photo.objects.all()``将返回数据库中所有的Photo对象,而Photo.on_site_all()仅根据SITE_ID设置返回与当前站点相关联的Photo对象。


换言之,以下两条语句是等效的:

Photo.objects.filter(site=settings.SITE_ID)

Photo.on_site.all()

CurrentSiteManager是如何知道Photo的哪个字段是Site呢?缺省情况下,它会查找一个叫做site的字段。如果模型中有个外键或多对多字段叫做site之外的名字,你必须显示地将它作为参数传递给CurrentSiteManager。下面的模型中有个叫做publish_on的字段,如下所示:

from django.db import models
from django.contrib.sites.models import Site
from django.contrib.sites.managers import CurrentSiteManager
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
photographer_name = models.CharField(maxlength=100)
pub_date = models.DateField()
publish_on = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager('publish_on')

如果试图使用CurrentSiteManager并传入一个不存在的字段名, Django将引发一个ValueError异常。


注意事项


即便是已经使用了CurrentSiteManager,你也许还想在模型中拥有一个正常的(非站点相关)的管理器。正如在附录
B 中所解释的,如果你手动定义了一个管理器,那么 Django不会为你创建全自动的objects = models.Manager()管理器。


同样,Django的特定部分——即 Django超级管理站点和通用视图——使用的管理器首先在模型中定义,因此如果希望超级管理站点能够访问所有对象(而不是仅仅站点特有对象),请于定义CurrentSiteManager之前在模型中放入objects
= models.Manager()。


Django如何使用多站点框架


尽管并不是必须的,我们还是强烈建议使用多站点框架,因为 Django在几个地方利用了它。即使只用 Django来支持单个网站,你也应该花一点时间用domain和name来创建站点对象,并将SITE_ID设置指向它的
ID 。


以下讲述的是 Django如何使用多站点框架:


§ 在重定向框架中(见后面的重定向一节),每一个重定向对象都与一个特定站点关联。当 Django搜索重定向的时候,它会考虑当前的SITE_ID。


§ 在注册框架中,每个注释都与特定站点相关。每个注释被张贴时,其site被设置为当前的SITE_ID,而当通过适当的模板标签列出注释时,只有当前站点的注释将会显示。


§ 在 flatpages框架中 (参见后面的
Flatpages一节),每个 flatpage都与特定的站点相关联。创建 flatpage时,你都将指定它的site,而
flatpage中间件在获取 flatpage以显示它的过程中,将查看当前的SITE_ID。


§ 在 syndication框架中(参阅Django输出非HTML内容),title和description的模板自动访问变量{{
site }},它就是代表当前着桨的Site对象。Also, the hook for providing item URLs will use thedomainfrom
the currentSiteobject if you dont specify a fully qualified domain.


§ 在身份验证框架(参见Django会话、用户和注册)中,django.contrib.auth.views.login视图将当前Site名称作为{{
site_name }}传递给模板。


Flatpages - 简单页面


尽管通常情况下总是建造和运行数据库驱动的 Web应用,你还是会需要添加一两张一次性的静态页面,例如“关于”页面,或者“隐私策略”页面等等。可以用像
Apache 这样的标准Web服务器来处理这些静态页面,但却会给应用带来一些额外的复杂性,因为你必须操心怎么配置 Apache,还要设置权限让整个团队可以修改编辑这些文件,而且你还不能使用
Django 模板系统来统一这些页面的风格。


这个问题的解决方案是使用位于django.contrib.flatpages开发包中的 Django简单页面(flatpages)应用程序。该应用让你能够通过
Django超级管理站点来管理这些一次性的页面,还可以让你使用 Django模板系统指定它们使用哪个模板。它在后台使用了 Django模型,也就是说它将页面存放在数据库中,你也可以像对待其他数据一样用标准
Django数据库 API 
存取简单页面。


简单页面以它们的 URL和站点为键值。当创建简单页面时,你指定它与哪个URL以及和哪个站点相关联。


使用简单页面


安装平页面应用程序必须按照下面的步骤:


1. 添加'django.contrib.flatpages'到INSTALLED_APPS设置。django.contrib.flatpages依赖于django.contrib.sites,所以确保这两个开发包都包括在``INSTALLED_APPS``设置中。


2. 将'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware'添加到MIDDLEWARE_CLASSES设置中。


3. 运行manage.py syncdb命令在数据库中创建必需的两个表。


简单页面应用程序在数据库中创建两个表:django_flatpage和django_flatpage_sites。django_flatpage只是将
URL 映射到到标题和一段文本内容。django_flatpage_sites是一个多对多表,用于关联某个简单页面以及一个或多个站点。


该应用所带来的FlatPage模型在django/contrib/flatpages/models.py进行定义,如下所示:

from django.db import models
from django.contrib.sites.models import Site
class FlatPage(models.Model):
url = models.CharField(maxlength=100)
title = models.CharField(maxlength=200)
content = models.TextField()
enable_comments = models.BooleanField()
template_name = models.CharField(maxlength=70, blank=True)
registration_required = models.BooleanField()
sites = models.ManyToManyField(Site)

让我们逐项看看这些字段的含义:


§ url:该简单页面所处的 URL,不包括域名,但是包含前导斜杠
(例如/about/contact/)。


§ title:简单页面的标题。框架不对它作任何特殊处理。由你通过模板来显示它。


§ content:简单页面的内容 (即HTML
页面)。框架不会对它作任何特别处理。由你负责使用模板来显示。


§ enable_comments:是否允许该简单页面使用注释。框架不对此做任何特别处理。你可在模板中检查该值并根据需要显示注释窗体。


§ template_name:用来解析该简单页面的模板名称。这是一个可选项;如果未指定模板或该模板不存在,系统会退而使用默认模板flatpages/default.html。


§ registration_required:是否注册用户才能查看此简单页面。该设置项集成了 Djangos验证/用户框架。


§ sites:该简单页面放置的站点。该项设置集成了 Django多站点框架,该框架在本章的《多站点》一节中有所阐述。


你可以通过 Django超级管理界面或者 Django数据库 API
来创建平页面。要了解更多内容,请查阅《添加、修改和删除简单页面》一节。


一旦简单页面创建完成,FlatpageFallbackMiddleware将完成(剩下)所有的工作。每当 Django引发
404 错误,作为终极手段,该中间件将根据所请求的 URL检查平页面数据库。确切地说,它将使用所指定的 URL以及SITE_ID设置对应的站点
ID查找一个简单页面。


如果找到一个匹配项,它将载入该简单页面的模板(如果没有指定的话,将使用默认模板flatpages/default.html)。同时,它把一个简单的上下文变量——flatpage(一个简单页面对象)传递给模板。在模板解析过程中,它实际用的是RequestContext。


如果FlatpageFallbackMiddleware没有找到匹配项,该请求继续如常处理。


注意


该中间件仅在发生 404(页面未找到)错误时被激活,而不会在 500(服务器错误)或其他错误响应时被激活。还要注意的是必须考虑MIDDLEWARE_CLASSES的顺序问题。通常,你可以把FlatpageFallbackMiddleware放在列表最后,因为它是一种终极手段。


添加、修改和删除简单页面


可以用两种方式增加、变更或删除简单页面:


通过超级管理界面


如果已经激活了自动的 Django超级管理界面,你将会在超级管理页面的首页看到有个 Flatpages区域。你可以像编辑系统中其它对象那样编辑简单页面。


通过 Python API


前面已经提到,简单页面表现为django/contrib/flatpages/models.py中的标准 Django模型。因此,你可以通过
Django数据库 API 
来存取简单页面对象,例如:

>>> from django.contrib.flatpages.models import FlatPage
>>> from django.contrib.sites.models import Site
>>> fp = FlatPage(
... url='/about/',
... title='About',
... content=&#39;<p>About this site...</p>&#39;,
... enable_comments=False,
... template_name=&#39;&#39;,
... registration_required=False,
... )
>>> fp.save()
>>> fp.sites.add(Site.objects.get(id=1))
>>> FlatPage.objects.get(url=&#39;/about/&#39;)
<FlatPage: /about/ -- About>

使用简单页面模板


缺省情况下,系统使用模板flatpages/default.html来解析简单页面,但你也可以通过设定FlatPage对象的template_name字段来覆盖特定简单页面的模板。


你必须自己创建flatpages/default.html模板。只需要在模板目录创建一个flatpages目录,并把default.html文件置于其中。


简单页面模板只接受有一个上下文变量——flatpage,也就是该简单页面对象。


以下是一个flatpages/default.html模板范例:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content }}
</body>
</html>

重定向


通过将重定向存储在数据库中并将其视为 Django模型对象,Django
重定向框架让你能够轻松地管理它们。比如说,你可以通过重定向框架告诉Django,把任何指向/music/的请求重定向到/sections/arts/music/。当你需要在站点中移动一些东西时,这项功能就派上用场了——网站开发者应该穷尽一切办法避免出现坏链接。


使用重定向框架


安装重定向应用程序必须遵循以下步骤:


1. 将'django.contrib.redirects'添加到INSTALLED_APPS设置中。


2. 将'django.contrib.redirects.middleware.RedirectFallbackMiddleware'添加到MIDDLEWARE_CLASSES设置中。


3. 运行manage.py syncdb命令将所需的表安装到数据库中。


manage.py syncdb在数据库中创建了一个django_redirect表。这是一个简单的查询表,只有site_id、old_path和new_path三个字段。


你可以通过 Django超级管理界面或者 Django数据库 API
来创建重定向。要了解更多信息,请参阅《增加、变更和删除重定向》一节。


一旦创建了重定向,RedirectFallbackMiddleware类将完成所有的工作。每当 Django应用引发一个
404 错误,作为终极手段,该中间件将为所请求的 URL在重定向数据库中进行查找。确切地说,它将使用给定的old_path以及SITE_ID设置对应的站点
ID查找重定向设置。(查阅前面的《多站点》一节可了解关于SITE_ID和多站点框架的更多细节)然后,它将执行以下两个步骤:


§ 如果找到了匹配项,并且new_path非空,它将重定向到new_path。


§ 如果找到了匹配项,但new_path为空,它将发送一个 410 (Gone) HTTP头信息以及一个空(无内容)响应。


§ 如果未找到匹配项,该请求将如常处理。


该中间件仅为 404错误激活,而不会为 500
错误或其他任何状态码的响应所激活。


注意必须考虑MIDDLEWARE_CLASSES的顺序。通常,你可以将RedirectFallbackMiddleware放置在列表的最后,因为它是一种终极手段。


注意


如果同时使用重定向和简单页面回退中间件,必须考虑先检查其中的哪一个(重定向或简单页面)。我们建议将简单页面放在重定向之前(因此将简单页面中间件放置在重定向中间件之前),但你可能有不同想法。


增加、变更和删除重定向


你可以两种方式增加、变更和删除重定向:


通过超级管理界面


如果已经激活了全自动的 Django超级管理界面,你应该能够在超级管理首页看到重定向区域。可以像编辑系统中其它对象一样编辑重定向。


通过 Python API


django/contrib/redirects/models.py中的一个标准 Django模型代表了重定向。因此,你可以通过 Django数据库
API 来存取重定向对象,例如:

>>> from django.contrib.redirects.models import Redirect
>>> from django.contrib.sites.models import Site
>>> red = Redirect(
... site=Site.objects.get(id=1),
... old_path=&#39;/music/&#39;,
... new_path=&#39;/sections/arts/music/&#39;,
... )
>>> red.save()
>>> Redirect.objects.get(old_path=&#39;/music/&#39;)
<Redirect: /music/ ---> /sections/arts/music/>

CSRF 防护


django.contrib.csrf开发包能够防止遭受跨站请求伪造攻击 (CSRF).


CSRF, 又叫进程跳转,是一种网站安全攻击技术。当某个恶意网站在用户未察觉的情况下将其从一个已经通过身份验证的站点诱骗至一个新的 URL时,这种攻击就发生了,因此它可以利用用户已经通过身份验证的状态。开始的时候,要理解这种攻击技术比较困难,因此我们在本节将使用两个例子来说明。


一个简单的 CSRF例子


假定你已经登录到example.com的网页邮件账号。该网页邮件站点上有一个登出按钮指向了 URLexample.com/logout,换句话说,要登出的话,需要做的唯一动作就是访问
URL :example.com/logout。


通过在(恶意)网页上用隐藏一个指向 URLexample.com/logout的d5ba1642137c3f32f4f4493ae923989c,恶意网站可以强迫你访问该
URL 。因此,如果你登录example.com的网页邮件账号之后,访问了带有指向example.com/logout之d5ba1642137c3f32f4f4493ae923989c的恶意站点,访问该恶意页面的动作将使你登出example.com。


诚然,对你而言登出一个网页邮件站点并不会构成多大的安全破坏,但同样的攻击可能发生在任何信任用户的站点之上,比如在线银行网站或者电子商务网站。


稍微复杂一点的CSRF例子


이전 예에서 example.com은 HTTP GET 메서드를 통해 상태 변경(예: 로그인 및 로그아웃)을 허용하므로 부분적으로 책임이 있습니다. 서버 상태 변경에
HTTPPOST 메서드가 필요하다면 상황은 훨씬 나아질 것입니다. 그러나 상태 변경 작업에 POST 메서드를 사용해야 하는 경우에도 여전히 CSRF 공격에 취약합니다.


example.com이 로그아웃 기능을 업그레이드했다고 가정합니다. ff9c23ada1bcecdd1a0fb5d5a0f18437 URLexample.com/logout을 가리키는 POST 작업을 통해 완료됩니다. 동시에 다음 숨겨진 필드가 ff9c23ada1bcecdd1a0fb5d5a0f18437에 추가됩니다:

1e7df074b3cd0e2460b69627e263070a

이는 사용자가 example.com/logout에 대한 간단한 POST로 사용자를 로그아웃시키지 않도록 하며, 사용자는 example.com/logout에 POST 요청을 보내고 값이 '인 POST 변수를 보내야 합니다. 진실'.


추가 보안 메커니즘에도 불구하고 이 디자인은 여전히 ​​CSRF 공격에 취약합니다. 악성 페이지는 약간의 개선만 필요합니다. 공격자는 사이트의 전체 양식을 대상으로 삼아 보이지 않는 d5ba1642137c3f32f4f4493ae923989c에 숨긴 다음
Javascript를 사용하여 자동으로 양식을 제출할 수 있습니다.


CSRF 예방


그럼 이 공격으로부터 사이트를 안전하게 만드는 것이 가능할까요? 첫 번째 단계는 모든 GET 메소드에 부작용이 없는지 확인하는 것입니다. 이렇게 하면 악성 사이트에 귀하의 페이지가 d5ba1642137c3f32f4f4493ae923989c으로 포함되어 있어도 부정적인 결과가 발생하지 않습니다.


이 기술은 POST 요청을 고려하지 않습니다. 두 번째 단계는 모든 POST

에 숨겨진 필드를 제공하는 것입니다. 이 필드의 값은 기밀이며 사용자 프로세스의
ID를 기반으로 생성됩니다. 이런 방식으로 서버 측에서 양식에 접근할 때 기밀 필드를 확인하고 일치하지 않으면 오류가 발생할 수 있습니다.


다음 하위 섹션에서 설명하는 것처럼 이것이 바로 Django CSRF 가드 레이어가 수행하는 작업입니다.


CSRF 미들웨어 사용


django.contrib.csrf 개발 패키지에는 middleware.py라는 하나의 모듈만 있습니다. 이 모듈에는
CSRF 보호 기능을 구현하는 Django 미들웨어 클래스인 CsrfMiddleware가 포함되어 있습니다.


설정 파일의 MIDDLEWARE_CLASSES 설정에 'django.contrib.csrf.middleware.CsrfMiddleware'를 추가하여
CSRF 보호를 활성화하세요. 이 미들웨어는 SessionMiddleware 다음에 실행되어야 하므로 목록에서 CsrfMiddleware가 SessionMiddleware 앞에 나타나야 합니다(응답 미들웨어는 뒤에서 앞으로 실행되기 때문입니다). 동시에 응답을 압축하거나 압축을 풀기 전에 응답 결과도 처리해야 하므로 GZipMiddleware 다음에 CsrfMiddleware를 실행해야 합니다. MIDDLEWARE_CLASSES 설정에 추가하면 작업이 완료됩니다.


관심이 있으시다면 CsrfMiddleware의 작동 모드는 다음과 같습니다. 다음 두 가지 작업을 완료합니다.


1. 현재 처리된 요청을 수정하고 모든 POST 양식에 숨겨진 양식 필드를 추가합니다. 사용 이름은 csrfmiddlewaretoken이고 값은 다음과 같습니다. 현재 세션
ID와 키 해시. 세션 ID가 설정되지 않은 경우 미들웨어는 응답 결과를 수정하지 않으므로 세션을 사용하지 않는 요청에 대한 성능 저하는 무시할 수 있습니다.


2. 세션 쿠키 수집을 통해 들어오는 모든 POST 요청에 대해 csrfmiddlewaretoken이 존재하는지와 올바른지 확인합니다. 그렇지 않은 경우 사용자는
403 HTTP 오류를 받게 됩니다. 403 오류 페이지의 내용은 다음 메시지입니다: 교차 사이트 위장 요청이 감지되었습니다. 요청이 종료되었습니다. ”


이 단계에서는 사이트에서 생성된 양식만 POST 데이터를 다시 보낼 수 있습니다.


이 중간 이 파일. 특히 HTTPPOST 요청(및 해당 POST 형식)만 대상으로 합니다. 설명했듯이 GET 요청 사용으로 인해 부정적인 영향이 있어서는 안 됩니다.

세션 쿠키를 사용하지 않는 POST 요청은 이를 수행할 수 없습니다. 🎜>HTML이 아닌 요청을 변환하지 않기 위해 미들웨어는 응답을 편집하기 전에 Content-Type 헤더를 확인합니다. /html 또는 application/xml+xhtml이 수정됩니다. 🎜>

CSRF 미들웨어의 제한 사항


CsrfMiddleware를 실행하려면 Django의 세션 프레임워크가 필요합니다. 사용자 정의 세션 또는 ID를 사용하는 경우 유효성 검사 프레임워크는 세션 쿠키를 수동으로 관리하며 애플리케이션이 색다른 방식으로 페이지를 생성하는 경우(예: Javascript 문서에서

HTML 조각 전송) 이 미들웨어는 도움이 되지 않습니다. write 문), 양식에 숨겨진 필드를 추가하는 필터를 우회하고 있을 수 있습니다(이는 양식 제출이 결코 성공하지 않기 때문입니다. CsrfMiddleware는 페이지가 클라이언트에 전송되기 전에 정규식을 사용하여 csrfmiddlewaretoken 필드를 HTML에 추가합니다. 때로는 정규 표현식이 기존의 HTML이 아닌

HTML을 처리하지 못할 수도 있습니다. 이런 일이 발생한다고 의심되면 브라우저에서 열어서 소스 코드 형식에 csrfmiddlewaretoken이 삽입되었는지 확인하세요.

CSRF에 대한 더 많은 정보와 예시를 알고 싶다면 http://en.wikipedia.org/wiki/CSRF를 방문하세요.


데이터를 인간화


앱에는 데이터 변경에 인간적 손길을 추가하기 위한 일련의 Django 템플릿 필터가 포함되어 있습니다. . 이러한 필터를 활성화하려면 INSTALLED_APPS 설정에 'django.contrib.humanize'를 추가하면 됩니다. 이 작업이 완료되면 템플릿에서 {%
load humanize %}를 사용하여 다음 섹션에 설명된 필터에 액세스하세요.


apnumber


숫자 1
~9의 경우 이 필터는 숫자의 철자를 반환합니다. 그렇지 않으면 숫자를 반환합니다. 이는 AP 스타일을 따릅니다.


예:


§ 1
이 1이 됩니다.


§ 2
둘이 됩니다.


§ 10
은 10 이 됩니다.


정수 또는 정수를 나타내는 문자열을 전달할 수 있습니다.


intcomma


이 필터는 정수를 쉼표로 구분된 세 자리마다 문자열로 변환합니다.


예:


§ 4500은 4,500
이 됩니다.


§ 45000이 45,000이 됩니다
.


§ 450000이 450,000이 됩니다
.


§ 4,500,000이 4,500,000이 됩니다
.


정수 또는 정수를 나타내는 문자열을 전달할 수 있습니다.


intword


이 필터는 큰 정수를 친숙한 텍스트 표현으로 변환합니다. 백만 개가 넘는 숫자에 가장 적합합니다.


예:


§ 1000000은 100만
이 됩니다.


§ 1,200,000이 120만이 됩니다
.


§ 1200000000이 12억이 됩니다
.


최대 지원액은 천의 5제곱(1,000,000,000,000,000)을 초과하지 않습니다.


정수 또는 정수를 나타내는 문자열을 전달할 수 있습니다.


서수


이 필터는 정수를 서수 단어의 문자열 형식으로 변환합니다.


예:


§ 1
이 1위가 됩니다.


§ 2
가 2위가 됩니다.


§ 3
3위가 됩니다.


정수 또는 정수를 나타내는 문자열을 전달할 수 있습니다.


마크업 필터


다음 템플릿 필터 컬렉션은 일반적인 마크업 언어를 구현합니다.


§ 텍스타일: 구현 텍스타일(http://en.wikipedia.org/wiki/Textile_%28markup_언어%29)


§ 마크다운: 구현 마크다운(http://en.wikipedia.org/wiki/Markdown)


§ 재구성된 텍스트: 재구성된 텍스트 구현(http://en.wikipedia.org/wiki/ ReStructuredText)


각 경우에 필터는 서식 지정 마크업을 문자열로 예상하고 마크업 텍스트를 나타내는 문자열을 반환합니다. 예를 들어 직물 필터는 직물 형식으로 표시된 텍스트를
HTML로 변환합니다.

{% 로드 마크업 %}


{{ object.content|textile }}

이 필터를 활성화하려면 ' django.contrib.markup'을 INSTALLED_APPS 설정으로 변경하세요. 이 작업이 완료되면 템플릿에서 {%
로드 마크업 %}을 사용하여 이러한 필터를 사용하세요. 자세한 내용은 django/contrib/markup/templatetags/markup.py의 소스 코드를 읽어보세요.

위 내용은 Django가 통합한 서브 프레임워크 내용입니다. 더 많은 관련 내용은 PHP 중국어 홈페이지(www.php.cn)를 참고해주세요!


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.