Maison > Article > développement back-end > Sous-framework intégré Django
Python présente de nombreux avantages, dont l'un est le principe du « prêt à l'emploi » : lors de l'installation de Python, un grand nombre de logiciels standards sont installés en même temps, afin que vous puissiez l'utiliser immédiatement sans avoir à le faire. téléchargez-le vous-même. Django suit également ce principe et inclut également sa propre bibliothèque standard. Ce chapitre parlera de ces sous-cadres intégrés.
Bibliothèque standard de Django
La bibliothèque standard de Django est placée dans le package django.contrib. Chaque sous-package est un package indépendant de fonctionnalités supplémentaires. Ils ne sont généralement pas nécessairement liés les uns aux autres, mais certains sous-packages django.contrib peuvent dépendre d'autres packages.
Il n'y a aucune exigence obligatoire pour le type de fonctions dans django.contrib. Certains de ces packages sont livrés avec des modèles (vous obligeant ainsi à installer les tables correspondantes dans votre base de données), mais d'autres sont constitués d'un middleware autonome et de balises de modèle.
La caractéristique commune du package de développement django.contrib est la suivante : même si vous supprimez l'intégralité du package de développement django.contrib, vous pouvez toujours utiliser les fonctions de base de
Django sans rencontrer de problèmes. Lorsque les développeurs Django ajoutent de nouvelles fonctionnalités au framework, ils suivront strictement cette doctrine lorsqu'ils décideront de mettre ou non la nouvelle fonctionnalité dans Django.contrib.
django.contrib est constitué des packages de développement suivants :
§ admin : outil de gestion automatisée de site. Veuillez consulter le site d'administration de Django
§ auth : le cadre d'authentification des utilisateurs de Django. Veuillez vérifier les sessions, les utilisateurs et les inscriptions
§ commentaires : Une application de commentaires Actuellement, cette application est en développement intense, elle ne peut donc pas être donnée au moment de la publication de ceci. book. Une description complète et plus d'informations sur cette application peuvent être trouvées sur le site officiel de Django
§ contenttypes : Il s'agit d'un framework pour les hooks de type document, chaque module Django est. installé en tant que type de document autonome. Ce framework est principalement utilisé dans Django par d'autres applications, et il est principalement destiné aux développeurs Django avancés. Vous pouvez en savoir plus sur ce framework en lisant le code source. Le code source se trouve dans django/contrib/contenttypes/.
§ csrf : Ce module est utilisé pour empêcher. Contrefaçon de demande intersite (CSRF). Consultez la section suivante intitulée « Défense CSRF ».
§ flatpages : Un module qui gère un contenu HTML unique dans une base de données, voir la section intitulée "Flatpages" ci-dessous.
§ humaniser : Une série de filtres de modules Django
utilisés pour augmenter l'humanisation des données.
§ balisage : une série de filtres de modèles Django
utilisés pour implémenter certains langages de balisage courants.
§ redirections : Un framework utilisé pour gérer les redirections.
§ sessions : le cadre de session de Django, voir les sessions, les utilisateurs et l'inscription.
§ plans de site : Un framework pour générer des fichiers XML
pour les plans de site. Voir Django produisant du contenu non HTML.
§ sites : Un framework qui vous permet de gérer plusieurs sites Web au sein de la même base de données et de l'installation de Django.
§ syndication : Un framework pour générer des flux de syndication à l'aide de RSS
et Atom. Voir Django produisant du contenu non HTML.
Ce qui suit dans ce chapitre décrira en détail le contenu du package de développement django.contrib qui n'a pas été introduit auparavant.
Sites multiples
Le système multisite de Django est un cadre universel qui vous permet d'exploiter plusieurs sites Web sous une seule base de données et le même projet Django. Il s’agit d’un concept abstrait qui peut être un peu difficile à comprendre, alors commençons par quelques scénarios pratiques où il peut s’avérer utile.
Scénario 1 : Réutiliser les données pour plusieurs sites
Comme nous l'avons dit au chapitre 1, les sites Web LJWorld.com et Lawrance.com
construits avec Django sont contrôlés par la même organisation de presse : The Lawrence Journal à Lawrence, Kansas World Newspapers. LJWorld.com se concentre sur l'actualité, tandis que
Lawrence.com se concentre sur le divertissement local. Parfois, cependant, un éditeur peut être amené à publier un article sur deux sites Web.
Une solution sans issue à ce problème pourrait être d'utiliser une base de données différente pour chaque site, puis de demander au responsable du site de publier deux fois le même article : une fois pour LJWorld .com et une autre fois Lawrence.com. Mais cela est inefficace pour les administrateurs de sites et conserver plusieurs copies du même article dans la base de données est redondant.
Une meilleure solution ? Les deux sites Web utilisent la même base de données d'articles et associent chaque article à un ou plusieurs sites via une relation plusieurs-à-plusieurs. Le framework de site Django fournit une base de données qui enregistre les articles pouvant être associés. C'est un hook qui associe des données à un ou plusieurs sites.
Scénario 2 : Stockez le nom/domaine de votre site Web dans un emplacement unique
LJWorld.com et Lawrence .com dispose d'une fonction de rappel par e-mail, permettant aux lecteurs de recevoir des notifications immédiatement après l'apparition d'une nouvelle après leur inscription. C'est un mécanisme parfait : un lecteur soumet un formulaire d'inscription et reçoit immédiatement un e-mail de « Merci pour votre inscription ».
Il est évidemment inefficace et redondant d'implémenter deux fois le code de ce processus d'inscription, les deux sites utilisent donc le même code en arrière-plan. Mais la notification vous remerciant de votre inscription doit être différente sur les deux sites Web. En utilisant l'objet Site, nous pouvons extraire la notification de remerciement en utilisant le nom du site actuel (par exemple, « LJWorld.com ») et le domaine (par exemple, « www.ljworld.com »).
Le framework multisite de Django vous offre un emplacement pour stocker le nom et le domaine de chaque site dans votre projet Django, ce qui signifie que vous pouvez les réutiliser de la même manière ces valeurs.
Comment utiliser le framework multi-sites
Le framework multi-sites n'est pas tant un framework que c'est une série de conventions. Tout repose sur deux concepts simples :
§ Le modèle de Site situé dans django.contrib.sites comporte deux champs : domaine et nom.
§ Le paramètre SITE_ID spécifie l'ID de base de données de l'objet Site associé à un fichier de configuration spécifique.
La façon dont vous utilisez ces deux concepts dépend de vous, mais Django le fait automatiquement avec quelques conventions simples.
Pour installer une application multi-site, effectuez les étapes suivantes :
1. Changez 'django.contrib .sites 'Ajouter à INSTALLED_APPS.
2. Exécutez la commande manage.py syncdb pour installer la table django_site dans la base de données.
3. Ajoutez un ou plusieurs objets
'Site' via le backend de gestion Django ou via l'API Python. Créez un objet Site pour chaque site (ou domaine) pris en charge par le projet Django
.
4. Définissez une variable SITE_ID dans chaque fichier de paramètres. La valeur de cette variable doit être la base de données
ID de l'objet Site du site pris en charge par le fichier de configuration.
Fonctions du framework multi-site
Les sections suivantes décrivent plusieurs choses qui peuvent être accomplies avec le multi -cadre de chantier Travail.
Réutilisation des données sur plusieurs sites
Comme expliqué dans le premier scénario, réutilisation des données sur plusieurs sites Pour réutiliser les données entre sites, il vous suffit d'ajouter un champ plusieurs-à-plusieurs pour Site dans le modèle, par exemple :
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)
Il s'agit de l'étape de base pour effectuer des opérations d'association d'articles pour plusieurs sites dans la base de données. En utilisant cette technique en place, vous pouvez réutiliser le même morceau de code de vue Django sur plusieurs sites. En continuant avec l'exemple de modèle d'article, voici une vue article_detail possible :
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
# ...
Cette méthode d'affichage est réutilisable car elle vérifie dynamiquement les articles en fonction de la valeur définie par SITE_ID. site.
Par exemple, le fichier de paramètres LJWorld.coms a un SITE_ID défini sur 1, et
Le fichier de paramètres Lawrence.coms a un SITE_ID défini sur 2. Si cette vue est appelée alors que LJWorld.coms est actif, elle limitera la recherche aux articles dont la liste de sites inclut
LJWorld.com.
Associer du contenu à un seul site
De même, vous pouvez également utiliser des clés étrangères dans plusieurs à un relations Associer un modèle au modèle Site.
Par exemple, si un certain article ne peut apparaître que sur un seul site, vous pouvez utiliser le modèle suivant :
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)
C'est la même chose que Les mêmes avantages que ceux introduits dans la section précédente.
Hook le site actuel depuis la vue
Sous le capot, en utilisant le framework multisite dans une vue Django , vous pouvez demander à la vue de faire différentes choses en fonction du site appelant, par exemple :
from django.conf import settings def my_view(request): if settings.SITE_ID == 3: # Do something. else: # Do something else.
Bien sûr, coder en dur l'ID du site comme ça est moche. Un moyen légèrement plus simple d'y parvenir consiste à afficher le domaine actuel du site :
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.
Il est courant d'obtenir la valeur settings.SITE_ID à partir de l'objet Site, donc le gestionnaire de modèles de site
(Site. objets) a une méthode get_current(). L'exemple suivant est équivalent au précédent :
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.
A noter que
dans ce dernier exemple Ici , vous n'avez pas besoin d'importer django.conf.settings.
Obtenir le domaine actuel pour le rendu
Comme expliqué dans le scénario deux, pour stocker le nom du site et le nom de domaine Pour Avec la méthode DRY (Dont Repeat Yourself) (stocker le nom du site et le nom de domaine au même endroit), il vous suffit de référencer le nom et le domaine de l'objet Site actuel. Par exemple :
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]) # ...
Pour continuer avec l'exemple de LJWorld.com et Lawrence.com
dont nous parlions, sur Lawrence.com
la ligne d'objet de l'e-mail est "Merci de vous être inscrit à l'e-mail de rappel Lawrence.com". Sur
LJWorld.com, la ligne d'objet de l'e-mail est "Merci de vous être inscrit à l'e-mail de rappel de LJWorld.com". Ce comportement lié au site s'applique également aux sujets des messages électroniques.
Une manière plus flexible (mais plus lourde) de procéder consiste à utiliser le système de modèles de Django. En supposant que Lawrence.com et
LJWorld.com ont chacun des répertoires de modèles différents (TEMPLATE_DIRS), vous pouvez facilement transférer le travail vers le système de modèles comme suit :
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]) # ...
Dans cet exemple, vous devez créer un modèle subject.txt et message.txt dans les répertoires de modèles de LJWorld.com et Lawrence.com
. Comme indiqué précédemment, cette approche apporte plus de flexibilité, mais aussi plus de complexité.
Utiliser autant d'objets Site que possible est un bon moyen de réduire les travaux inutiles, complexes et redondants.
Obtenir l'URL complète du domaine actuel
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的d5ba1642137c3f32f4f4493ae923989c,恶意网站可以强迫你访问该
URL 。因此,如果你登录example.com的网页邮件账号之后,访问了带有指向example.com/logout之d5ba1642137c3f32f4f4493ae923989c的恶意站点,访问该恶意页面的动作将使你登出example.com。
诚然,对你而言登出一个网页邮件站点并不会构成多大的安全破坏,但同样的攻击可能发生在任何信任用户的站点之上,比如在线银行网站或者电子商务网站。
稍微复杂一点的CSRF例子
Dans l'exemple précédent, example.com est partiellement responsable car il autorise les changements de statut (c'est-à-dire la connexion et la déconnexion) via la méthode HTTP GET. La situation serait bien meilleure si la méthode
HTTPPOST était requise pour les changements d'état du serveur. Cependant, même s’il est obligatoire d’utiliser la méthode POST pour les opérations de changement d’état, elle reste vulnérable aux attaques CSRF.
Supposons que example.com ait mis à niveau la fonction de déconnexion. La déconnexion du bouton ff9c23ada1bcecdd1a0fb5d5a0f18437 est effectuée via une action POST pointant vers l'URLexample.com/logout. En même temps, dans Les champs masqués suivants sont ajoutés au ff9c23ada1bcecdd1a0fb5d5a0f18437 :
1e7df074b3cd0e2460b69627e263070a
Cela garantit que les utilisateurs Un simple POST sur example.com/logout ne déconnectera pas l'utilisateur ; pour se déconnecter, l'utilisateur doit envoyer une requête POST à example.com/logout et envoyer une variable POST avec une valeur de ' vrai'.
Malgré les mécanismes de sécurité supplémentaires, cette conception est toujours sensible aux attaques CSRF - la page malveillante n'a besoin que d'une petite amélioration. Un attaquant pourrait cibler un formulaire entier sur votre site, le masquer dans un d5ba1642137c3f32f4f4493ae923989c invisible, puis utiliser
Javascript pour soumettre automatiquement le formulaire.
Prévenir CSRF
Alors, est-il possible de mettre un site à l'abri de cette attaque ? La première étape consiste à s’assurer que toutes les méthodes GET n’ont aucun effet secondaire. De cette façon, si un site malveillant inclut votre page en tant que d5ba1642137c3f32f4f4493ae923989c, cela n'aura pas de conséquences négatives.
Cette technique ne prend pas en compte les requêtes POST. La deuxième étape consiste à donner à tous les POST ff9c23ada1bcecdd1a0fb5d5a0f18437 un champ caché, dont la valeur est confidentielle et générée en fonction de l'
ID du processus utilisateur. De cette manière, lors de l'accès au formulaire depuis le serveur, les champs confidentiels peuvent être vérifiés et une erreur peut être générée s'ils ne correspondent pas.
C'est exactement ce que fait la couche de garde Django CSRF, comme expliqué dans les sous-sections suivantes.
Utilisation du middleware CSRF
Le package de développement django.contrib.csrf n'a qu'un seul module : middleware.py. Ce module contient une classe middleware Django - CsrfMiddleware, qui implémente la fonction de protection
CSRF.
Ajoutez 'django.contrib.csrf.middleware.CsrfMiddleware' au paramètre MIDDLEWARE_CLASSES dans le fichier de paramètres pour activer la
protection CSRF. Ce middleware doit être exécuté après SessionMiddleware, donc CsrfMiddleware doit apparaître avant SessionMiddleware dans la liste (car le middleware de réponse est exécuté de l'arrière vers l'avant). Dans le même temps, il doit également traiter les résultats de la réponse avant que la réponse ne soit compressée ou décompressée, donc CsrfMiddleware doit être exécuté après GZipMiddleware. Une fois que vous l'avez ajouté au paramètre MIDDLEWARE_CLASSES, vous avez terminé.
Si vous êtes intéressé, voici le mode de fonctionnement de CsrfMiddleware. Il effectue les deux tâches suivantes :
1. Il modifie la requête actuellement traitée et ajoute un champ de formulaire masqué à tous les formulaires POST. Le nom d'utilisation est csrfmiddlewaretoken et la valeur est. L'ID de session en cours
plus un hachage de la clé. Si l'ID de session n'est pas défini, le middleware ne modifiera pas le résultat de la réponse, la pénalité en termes de performances est donc négligeable pour les requêtes qui n'utilisent pas de session.
2. Pour toutes les requêtes POST entrantes avec collecte de cookies de session, il vérifiera si le csrfmiddlewaretoken existe et s'il est correct. Sinon, l'utilisateur recevra une
erreur HTTP 403. Le contenu de la page d'erreur 403 est le message : Demande de masquage intersites détectée. La demande a été interrompue. ”
Cette étape garantit que seuls les formulaires provenant de votre site peuvent renvoyer les données
Ce milieu Ce fichier. cible spécifiquement uniquement les requêtes HTTPPOST (et le formulaire POST correspondant). Comme nous l'avons expliqué, l'utilisation des requêtes GET ne devrait jamais avoir d'effets négatifs, vous devez vous en assurer vous-même.
Les requêtes POST qui n'utilisent pas de cookies de session ne peuvent pas le faire. être protégés, mais ils n'ont pas besoin d'être protégés car les sites Web malveillants peuvent faire de telles requêtes de quelque manière que ce soit. 🎜>Pour éviter de convertir des requêtes non HTML, le middleware vérifie l'en-tête Content-Type avant de modifier la réponse uniquement les pages marquées comme texte. /html ou application/xml xhtml sera modifié.>
Limitations du middleware CSRF
CsrfMiddleware nécessite l'exécution du framework de session de Django si vous l'utilisez. sessions personnalisées ou authentification. Le framework gère les cookies de session manuellement, et ce middleware ne vous aidera pas si votre application crée des pages HTML de manière non conventionnelle (par exemple : envoi du fragment HTML
dans l'instruction document.write de Javascript), vous contournez peut-être le filtre qui ajoute un champ masqué au formulaire, auquel cas la soumission du formulaire ne réussira jamais. CsrfMiddleware utilise des expressions régulières pour ajouter le champ csrfmiddlewaretoken au code HTML avant que la page ne soit envoyée au client, et parfois des expressions régulières. ne peut pas gérer leHTML non conventionnel) Si vous soupçonnez que ce genre de chose se produit, vérifiez-le simplement dans votre navigateur. Vérifiez si le csrfmiddlewaretoken a été inséré dans le formulaire du code source.
Si vous souhaitez en savoir plus et des exemples sur CSRF, vous pouvez visiter http://en.wikipedia.org/wiki/CSRF.
Humaniser les données
L'application comprend une série de filtres de modèles Django pour ajouter une touche humaine à vos modifications de données . Pour activer ces filtres, ajoutez simplement « django.contrib.humanize » au paramètre INSTALLED_APPS. Une fois cela fait, utilisez {%
load humanize %} dans le modèle pour accéder aux filtres décrits dans les sections suivantes.
apnumber
Pour les numéros 1
à 9, ce filtre renvoie l'orthographe du numéro. Sinon, il renvoie un nombre. Cela suit le style AP.
Exemple :
§ 1
devient un.
§2
devient deux.
§ 10
devient 10 .
Vous pouvez transmettre un entier ou une chaîne représentant un entier.
intcomma
Ce filtre convertit un entier en chaîne avec tous les trois chiffres séparés par une virgule.
Par exemple :
§ 4500 devient 4,500
.
§ 45000 devient 45,000
.
§ 450000 devient 450 000
.
§ 4 500 000 devient 4 500 000
.
Vous pouvez transmettre un entier ou une chaîne représentant un entier.
intword
Ce filtre convertit un grand entier en une représentation textuelle conviviale. Cela fonctionne mieux pour les nombres supérieurs à un million.
Par exemple :
§ 1000000 devient 1,0 million
.
§ 1 200 000 devient 1,2 million
.
§ 1200000000 devient 1,2 milliard
.
Le support maximum ne dépasse pas la cinquième puissance de mille (1 000 000 000 000 000).
Vous pouvez transmettre un entier ou une chaîne représentant un entier.
ordinal
Ce filtre convertit un entier en la forme chaîne d'un mot ordinal.
Par exemple :
§ 1
devient 1er.
§2
devient 2ème.
§3
devient 3ème.
Vous pouvez transmettre un entier ou une chaîne représentant un entier.
Filtres de balisage
La collection de filtres de modèles suivante implémente des langages de balisage courants :
§ textile : implémente Textile (http://en.wikipedia.org/wiki/Textile_(markup_lingual))
§ markdown : implémente Markdown (http://en.wikipedia.org/wiki/Markdown)
§ texte restructuré : implémente le texte restructuré (http://en.wikipedia .org/wiki/ReStructuredText )
Dans chaque cas, le filtre attend le balisage de formatage sous forme de chaîne et renvoie une chaîne représentant le texte de balisage. Par exemple : le filtre textile convertit le texte marqué au format Textile en
HTML.
{% load markup %}
{{ object.content|textile }}
Pour activer ces filtres, ajoutez simplement ' django.contrib.markup' au paramètre INSTALLED_APPS. Une fois cela fait, utilisez {%
load markup %} dans le modèle pour utiliser ces filtres. Pour plus d'informations, lisez le code source dans django/contrib/markup/templatetags/markup.py.
Ce qui précède est le contenu du sous-framework intégré par Django. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn) !