Django开发——集成的子框架django.contrib

2018年09月11日 19:32:42 Mrkang1314 阅读数:63
 https://blog.csdn.net/mashaokang1314/article/details/82431705

Django标准库

Django的标准库存放在django.contrib包中。每个子包都是一个独立的附加包,这些子包一般都是相互独立的,不过有些子包需要依赖其他子包。
django.contrib开发包共有的特性是:就算你将整个django.contrib开发包删除,你依然可以使用Django的基础功能而不会遇到任何问题。
django.contrib由以下开发包组成:

  • admin:自动化的站点管理;
  • admindocs:为Django admin站点提供自动文档;
  • auth:Django的用户验证框架;
  • comments:一个评论应用;
  • contenttypes:一个用于引入文档类型的框架,每个安装的Django模块作为一种独立的文档类型。
  • csrf:这个模块用来防御跨站请求伪造;
  • databrowse:帮助你浏览数据的一个用;
  • flatpages:一个在数据库中管理单一HTML内容的模块;
  • formtools:一些列表处理表单通用模式的高级库;
  • gis:为Django提供GIS支持的扩展;
  • humanize:一系列Django模块过滤器,用于增加数据的人性化。
  • localflavor:针对不同国家和文化的混杂代码段;
  • markup:一系列的Django模板过滤器;
  • redirects:用来管理重定向的框架;
  • sessions:Django会话框架;
  • sitemaps:用来生成网站地图的XML文件的框架;
  • sites:一个让你可以在同一个数据库与Django安装中管理多个网站的框架。
  • syndication:一个用RSS和Atom来生成聚合订阅源的框架;
  • webdesign:对设计者非常有用的Django扩展。

如何使用多站点框架
多站点框架:

  • 位于django.contrib.sites的site模型由domain和name两个字段。
  • SITE_ID设置指定了与特定配置文件相关联的site对象之数据库的ID。

安装多站点应用要执行以下几个步骤:

  • 将‘django.contrib.sites’加入到INSTALLED_APPS中。
  • 运行manage.py syncdb命令将django_site表安装到数据库中。这样也会建立默认的站点对象,域名为example.com
  • 把example.com改成自己的域名,然后通过Django admin站点或Python API来添加其他site对象。为该Django项目支撑的每个站点创建一个site对象。
  • 在每个设置文件中定义一个SITE_ID变量。该变量值应当是该设置文件所支撑的站点Site对象的数据库ID。

多站点框架的功能

多个站点的数据重用
要在多各站点间重用数据,仅需在模型中为site添加一个多对多字段即可:

from django.db import models
from django.contrib.sites.models import Site class Article(models.Model):
headline=models.CharField(max_length=200)
sites=models.ManyToManyField(Site)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在适当的位置使用这个技术,你可以在多站点中重度使用统一段Django视图代码。

from django.conf import settings
from django.shortcuts import get_object_or_404
from mysite.articles.models import Article
def article_detail(request, article_id):
a = get_object_or_404(Article, id=article_id, sites__id=settings.SITE_ID)
# ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

该视图方法是可重用的,因为它根据SITE_ID设置的值动态检查articles站点。
将内容与单一站点相关联
可以使用外键在多对一关系中将一个模型关联到site模型。

from django.db import models
from django.contrib.sites.models import Site
class Article(models.Model):
headline = models.CharField(max_length=200)
# ...
site = models.ForeignKey(Site)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

从视图钩挂当前站点
在底层,通过Django视图中使用多站点框架,可以让视图根据用站点不同而完成不同的工作。

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.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

从site对象中获得settings.SITE_ID值的做法比较常见,因此SIte模型管理具备一个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.
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

获取当前域用于呈现
依据DRY原则(不做重复工作),你只需在一个位置储存站点和域名,然后引用当前Site对象的name和domain。

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])
# ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

在Lawrence.com 该邮件的标题行是“感谢注册Lawrence.com 提醒信件”。 在 LJWorld.com ,该邮件标题行是“感谢注册 LJWorld.com 提醒信件”。 这种站点关联行为方式对邮件信息主体也同样适用。
完成这项工作的一种更加灵活的方法是使用Django的模板系统。假定Lawrence.com和LJWorld.com拥有各子不同的模板目录,可以将工作轻松地转交给模板系统。

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])
# ...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当前站点管理器

如果站点在你的应用中扮演很重要的角色,请考虑在你的模型中使用方便的
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(max_length=100)
pub_date = models.DateField()
site = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

Photo.objects.filter(site=settings.SITE_ID)
Photo.on_site.all()
  • 1
  • 2

这两条是等价的。
CurrentSiteManager是如何知道Photo的哪个字段是Site呢?缺省情况下,它会查找一个叫做site的字段。如果你的模型包含不是site的外键或者多对多关联,需要把它作为参数传给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(max_length=100)
pub_date = models.DateField()
publish_on = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager('publish_on')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果传入一个不存在的字段名,则会引发异常。
Django的特定部分(即Django超级管理站点和通用视图)使用在模型中定义的第一个管理器,因此如果希望管理站点能够访问所有对象,请于定义CurrentSiteManager之前在模型中放入objects=models.Manager().

Django如何使用多站点框架

即是只用Django来支持单个网站,也应该化一点时间用domain和name来创建站点对象,并将SITE_ID设置指向它的ID。
Django如何使用多站点框架:

  • 在重定向框架中,每一个重定向对象都与一个特定站点关联。当Django搜索重定向的时候,它会考虑当前的SITE_ID.
  • 在注册框架时,每个注释都与特定站点相关。每个注释被显示时,其site被设置为当前的SITE_ID,而当通过适当的模板标签列出注释时,只有当前站点的注释会显示。
  • 在flatpages框架中,每个flatpage都与特定的站点相关联。创建flatpage时,你将指定它的site,而flatpage中间件在获取flatpage以显示它的过程中。将查询当前的SITE_ID.
  • 在syndication框架中,title和description的模板会自动访问变量{{ site }},它其实是代表当前站点的site对象。如果你不指定一个合格的domain的话,提供目录URL的钩子将会使用当前的Site对象的domain。
  • 在权限框架中视图 django.contrib.auth.views.login 把当前 Site 名字和对象分别以 {{ site_name }} 和 {{ site }} 的形式传给了模板。

Flatpages(简单页面)

尽管通常情况下总是搭建运行数据库驱动的Web应用,有时还需要添加一两张一次性的静态网页,例如“关于”或者“隐私策略“页面等。可以用像Apache这样标准的Web服务器来处理这些静态页面,但却会给应用带来一些额外的复杂性,因为你西须操心怎么配置Apache,还要设置权限让整个团队可以修改编辑这些文件,而且不能使用Django模板系统来统一这些页面的风格。
这个问题的解决方案使用位于django.contrib.flatpages开发包中的Django简单页面应用程序。该应用让你能够通过Django管理站点来管理这些一次性的页面。还可以让你使用Django模板系统指定它们使用哪个模板。它在后台使用Django模型,这意味着它把页面像被的数据一样保存在数据库。
简单页面以它们的URL和站点为键值,当创建简单页面时,你指定与哪个URL以及和哪个站点相关联。
使用简单页面
安装简单页面步骤:

  • 添加 ‘django.contrib.flatpages’ 到 INSTALLED_APPS 设置。 django.contrib.flatpages 依赖 django.contrib.sites ,所以确保它们都在INSTALLED_APPS 里。
  • 将 ‘django.contrib.flatpages.middleware.FlatpageFallbackMiddleware’ 添加到 MIDDLEWARE_CLASSES设置中。
  • 用命令在数据库中创建必须的两个表。

django_flatpage只是将URL映射到标题和一段内容。django_flatpage_sites是一个多对多表,用于关联某个简单页面以及一个或多个站点。
该应用捆绑的FlatPage模型在django/contrib/flatpages/models.py中进行定义。

class FlatPage(models.Model):
url = models.CharField(_('URL'), max_length=100, db_index=True)
title = models.CharField(_('title'), max_length=200)
content = models.TextField(_('content'), blank=True)
enable_comments = models.BooleanField(_('enable comments'), default=False)
template_name = models.CharField(
_('template name'),
max_length=70,
blank=True,
help_text=_(
"Example: 'flatpages/contact_page.html'. If this isn't provided, "
"the system will use 'flatpages/default.html'."
),
)
registration_required = models.BooleanField(
_('registration required'),
help_text=_("If this is checked, only logged-in users will be able to view the page."),
default=False,
)
sites = models.ManyToManyField(Site, verbose_name=_('sites'))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • url:该简单页面所处的URL,不包括域名,单是包含前导斜杠。
  • title:标题;
  • content:内容;
  • enable_comments:是否允许该简单页面使用评论;
  • template_name:用来解析该简单页面的名称。可选项,如果未指定模板或者该模板不存在,系统会退而使用默认模板flatpages/defaults.html;
  • registration_required:是否注册用户才能看到此页面。
  • sites:该简单页面放置的站点。

一旦完成创建,FlatpageFallbackMiddleware将完成剩下的所有工作。每当Django引发404错误,作为最后的方法该中间件将根据所请求的URL检查简单页面数据库。具体的说,它将使用所指定的URL以及SITE_ID设置对应的站点ID查找一个简单的页面。如果找到一个匹配项,它将载入该简单页面的模板,同时它把一个简单的上下文变量flatpage传递给模板,模板解析过程,它实际用的是RequestContext。如果没有找到匹配项,该请求继续如常处理。该中间件仅在发生404错误是被激活,通常放在最后,因为这是它最后的办法。

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

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


通过Python API

>>> from django.contrib.flatpages.models import FlatPage
>>> from django.contrib.sites.models import Site
>>> f=FlatPage.objects.create(
... url='/about/',
... title='About',
... content='<p>About this site...</p>',
... enable_comments=False,
... templates_name='',
... registration_required=Flase
... )
>>> fp.sites.add(Site.objects.get(id=1))
>>> FlatPage.objects.get(url='/about/')
<FlatPage: /about/ ‐‐ About>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

使用简单页面模板
缺省情况下,使用模板flatpages/default.html来解析简单页面,也可以通过设定FlatPage对象的template_name字段来更待特定简单的模板。
必须自己创建flatpages/default.html模板,只需在模版目录创建一个flatpages目录,并把defalut.html文件置于其中。

<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content|safe }}
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用safe模板过滤器允许flatpage.content引入原始HTML而不必转意。

重定向

通过将重定向存储在数据库中并将其视为Djangp模型对象,Django重定向框架让你能够轻松管理它们。
使用重定向框架
步骤:

  • 将 ‘django.contrib.redirects’ 添加到 INSTALLED_APPS 设置中。
  • 将 ‘django.contrib.redirects.middleware.RedirectFallbackMiddleware’ 添加到 MIDDLEWARE_CLASSES设置中。

在数据库中创建一个django_redirect表。这个表只有site_id,old_path,new_path三个字段。
一旦创建了重定向,RedirectFallbackMiddleware类将完成所有工作。每当Django应用引发一个404错误,作为终极手段,该中间件将为所请求的URL在重定向数据库中进行查找。它将使用给定的old_path以及SITE_ID设置对应的站点ID查找重定向设置。

  • 如果找到匹配项,并且new_path非空,它将重定向到new_path;

  • 如果找到匹配项,单new_path为空,它将发送一个410HTTP头信息以及一个空向应。

  • 如果为找到匹配项,该请求如常处理。
    该中间件仅为404错误激活,将这个中间件放到列表最后,因为它是终极手段。
    注意:
    如果同时使用重定向和简单页面回退中间件,必须考虑先检查其中的哪一个。建议将简单页面放在重定向之前。
    增加、变更删除重定向

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

  • 重定向表现为django/contrib/redirects/models.py中的一个标准Django模型。所以可以通过Django数据库API来存取重定向对象。

>>> from django.contrib.redirects.models import Redirect
>>> from django.contrib.sites.models import Site
>>> red = Redirect.objects.create(
...
... site=Site.objects.get(id=1),
old_path='/music/',
... new_path='/sections/arts/music/',
... )
>>> Redirect.objects.get(old_path='/music/')
<Redirect: /music/ ‐‐‐> /sections/arts/music/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

CSRF防护

CSRF称为跨站请求伪造攻击,又叫会话跳转,可以利用用户已经通过身分验证的状态,诱骗至一个危险的URL。
防止CSRF
第一步,首先确保所有GET方法没有副作用。这样一来如果某个恶意站点将你的页面包含为iframe它将不会产生负面效果。
第二步就是给所有POST的form标签一个隐藏字段,它的值是保密的并根据用户进程的ID生成。这样从服务端访问表单时,可以检查该保密的字段,不吻合可以发生一个错误。

人性化数据

包 django.contrib.humanize 包含了一些是数据更人性化的模板过滤器。 要激活这些过滤器,请把 ‘django.contrib.humanize’ 加入到你的 INSTALLED_APPS 中。完成之后,向模版了加入 {% load humanize %} 就可以使用下面的过滤器了。

名称 用法
apnumber 对于1到9的数字,该过滤器返回了数字的拼写形式。否则,它将返回数字。
intcomma 将整数转换为每三个数字用一个逗号分隔的字符串
intword 将一个很大的整数转换成友好的文本表示方式,1200000 变成1.2million
ordinal 将整数转换为序数词的字符串形式
{% load humanize %}

{{ 1|apnumber }}
<br>
{{ 6|apnumber }}
<br>
{{ 45000000|intcomma }}
<br>
{{ 12000000|intword }}
<br>
{{ 5|ordinal }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12


标记过滤器
包 django.contrib.markup 包含了一些列Django模板过滤器,每一个都实现了一中通用的标记语言。

  • textile:实现了Textile;
  • markdown:实现了Markdown;
  • restructuredtext:实现了ReStructred Text.

每种情况下,过滤器都期望字符串形式的格式化标记,并返回表示标记文本的字符串。要激活这些过滤器,仅需将 ‘django.contrib.markup’ 添加到 INSTALLED_APPS 设置中。 一旦完成了该项工作,在模板中通过 {% load markup %} 就能使用这些过滤器。

Django开发——集成的子框架django.contrib的更多相关文章

  1. Django开发之路 一(django安装并测试运行)

    安装Django与测试 1.虚拟环境的安装 一般来说Django的开发最好是在虚拟环境上进行,这样的好处是可以将不同的Django的项目的环境分割开来,相互不影响.比如说项目一用到Python2.x和 ...

  2. Django开发之路 二(django的models表查询)

    django的models表查询 一.单表查询 (1) all(): 查询所有结果 # 返回的QuerySet类型 (2) filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 #返 ...

  3. django开发博客(1) 入门

    现在正式开始博客开发 1.安装django1.4 如果你使用的是fedoraDVD版,安装时选择了web开发组建,这一步可以省略,因为它自带django环境 django下载地址 https://ww ...

  4. python运维开发(十七)----jQuery续(示例)web框架django

    内容目录: jQuery示例 前端插件 web框架 Django框架 jQuery示例 dom事件绑定,dom绑定在form表单提交按钮地方都会绑定一个onclick事件,所有查看网站的人都能看到代码 ...

  5. Django快速开发实践:Drf框架和xadmin配置指北

    步骤 既然是快速开发,那废话不多说,直接说步骤: 安装Djagno 安装Django Rest Framework 定义models 定义Rest framework的serializers 定义Re ...

  6. Django 开发相关知识 整理

    前言 前端ajax HTTP请求头 ajax上传文件 jsonp跨域 URL 设计 分发 url参数编码 反向生成url 视图 request对象 POST url信息 视图返回值 HttpRespo ...

  7. Django开发自己的博客系统

    好久之前就想做一下自己的博客系统了,但是在网上查了查好像是需要会一些Node.js的相关知识,而且还要安装辣么多的库什么的,就不想碰了.但是我遇到了Django这么一款神器,没想到我的博客系统就这么建 ...

  8. web框架---django

    15:31:14一.web框架1.框架:即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统,简单地说,就是你用别人搭建好的舞台来做表演. ...

  9. Python 17 web框架&Django

    本节内容 1.html里面的正则表达式 2.web样式简介 3.Django创建工程 Html里的正则表达式 test 用来判断字符串是否符合规定的正则       rep.test('....')  ...

随机推荐

  1. Java问题:中间件是什么

    和朋友聊天时被问到中间件是什么?一时有点语赛,感觉熟悉这个概念,但又完全不知道如何清楚的向别人讲这些. 网络上搜了一下,也没找到让自己很认可的说法,有的说非业务的技术类组件,是操作系统之上和业务逻辑之 ...

  2. 一个detect问题引发的一系列思考

    在用BoneCP的时候,发现一个JVM日志中报了一个异常,大意是“探测(detect)到有数据库链接没有关闭”(不得不说JVM的强大),但是我用的是连接池里面的链接啊,怎么会需要关闭呢? 有问题首先找 ...

  3. php通过JavaBridge调用Java类库和不带包的自定义java类成功 但是调用带包的自定义Java类报错,该怎么解决

    php通过JavaBridge调用Java类库和不带包的自定义java类成功 但是调用带包的自定义Java类报错,Class.forName("com.mysql.jdbc.Driver&q ...

  4. bzoj 3612 [Heoi2014]平衡——整数划分(dp)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3612 因为力矩的缘故,变成了整数划分. 学习到了整数划分.就是那个图一样的套路.https: ...

  5. Python学习书籍推荐 中英对照

    Learn Python The Hard Way 笨办法学 python A Byte of Python 简明Python教程 初学者 英文版 Learning Python, 3rd Editi ...

  6. 安装S_S相关报错的troubleshooting

    在安装S_S server时,在Debian上会出现类似如下的报错: File , in <module> sys.exit(main()) File , in main config = ...

  7. linux平台总线驱动设备模型之点亮LED

    这一节里,我们来使用平台驱动设备这一套架构来实现我们之前使用简单的字符设备驱动点亮LED,这里并无实际意义,只是告诉大家如果编写平台总线驱动设备. 问:如何编写平台总线驱动设备这一套架构的设备驱动? ...

  8. String to Integer (atoi) ???

    #define INT_MAX 2147483647 #define INT_MIN -2147483648 class Solution { public: int atoi(const char ...

  9. 匿名类型与Select方法实现自定义对象插入局部表结构中

    在提取局部表结构数据时,通过Select选取需要的字段,如下句,此时其实产生了一个不用于_menuMan的原新数据类型new { c.SYS_COMMANDS_ID,c.TXT_COMMANDTITL ...

  10. 企业短信通 C# HTTP接口 发送短信

    /* 功能: 企业短信通 C# HTTP接口 发送短信 修改日期: 2014-09-01 说明: http://api.cnsms.cn/?ac=send&uid=用户账号&pwd=M ...