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='<p>About this site...</p>', ... enable_comments=False, ... template_name='', ... registration_required=False, ... ) >>> fp.save() >>> fp.sites.add(Site.objects.get(id=1)) >>> FlatPage.objects.get(url='/about/') <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='/music/', ... new_path='/sections/arts/music/', ... ) >>> red.save() >>> Redirect.objects.get(old_path='/music/') <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的
诚然,对你而言登出一个网页邮件站点并不会构成多大的安全破坏,但同样的攻击可能发生在任何信任用户的站点之上,比如在线银行网站或者电子商务网站。
稍微复杂一点的CSRF例子
이전 예에서 example.com은 HTTP GET 메서드를 통해 상태 변경(예: 로그인 및 로그아웃)을 허용하므로 부분적으로 책임이 있습니다. 서버 상태 변경에
HTTPPOST 메서드가 필요하다면 상황은 훨씬 나아질 것입니다. 그러나 상태 변경 작업에 POST 메서드를 사용해야 하는 경우에도 여전히 CSRF 공격에 취약합니다.
example.com이 로그아웃 기능을 업그레이드했다고 가정합니다.