95992828九五至尊2

882828九五至尊手机版Django框架周详授课

二月 26th, 2019  |  882828九五至尊手机版

一、Django 简介

  Django 是贰个由 Python 写成的开放源代码的 Web
应用框架。它最初是被开发来用于管理Lawrence出版公司旗下的有的以音讯内容为主的网站的,便是CMS(内容管理种类)软件。并于2006年五月在 BSD
许可证下发布。那套框架是以比利时的吉普赛爵士吉他手 Django Reinhardt
来命名的。由于 Django
的是在1个快节奏的消息编辑室环境下支付的,它的目标是使周边的 Web
开发职务,神速和容易。

 

Python的WEB框架有Django、Tornado、Flask
等两种,Django相较与其余WEB框架其优势为:大而全,框架自个儿集成了OENVISIONM、模型绑定、模板引擎、缓存、Session等众多成效。

MTV 模式

Django 采纳了 MTV 设计格局

882828九五至尊手机版 1

上述图大约是说:

  1. U汉兰达L ( urls.py )请求调度,当有缓存页面包车型地铁时候一直回到内容。
  2. 视图函数( view.py )执行所请求的操作,常常包涵读写数据库。
  3. 模型( models.py )定义了 Python
    中的数据并与之并行。平时包括在1个关周全据库( MySQL、PostgreSQL
    SQLite 等),其余数据存款和储蓄是唯恐的( XML、文本文件、LDAP、等)。
  4. 伸手执行任务后,视图再次回到两个 HTTP
    响应对象(日常是通过多少处理的一个模板)。可选的:视图能够保存1个版本的
    HTTP 响应对象,重返指导2个日子戳,来告诉浏览器这几个视图的更新时间。
  5. 模板日常重临 HTML 页面。Django 模板语言提供了 HTML 的语法及逻辑。

 882828九五至尊手机版 2

 

本文将以下地点带我们无微不至精晓Django框架,小编使用的版本为1.10.

 安装

# pip 安装
pip install Django==1.10

# 克隆下载最新版本
git clone https://github.com/django/django.git

# 导入django模块
>>> import django
>>> print(django.get_version())
1.10

 

  1. 流程

  2. 基本配备

  3. 路由系统
  4. 视图view
  5. 模板
  6. Model
  7. 中间件
  8. Form
  9. 证实系统
  10. CSRF
  11. 分页
  12. Cookie
  13. Seesion
  14. 缓存
  15. 序列化
  16. 信号
  17. admin

二 、基本配备

① 、 Django流程介绍

壹 、常用命令

# 查看django版本
$ python -m django --version

# 创建项目,名为mysite
$ django-admin startproject mysite

# 启动django
$ python manage.py runserver
$ python manage.py runserver 8080
$ python manage.py runserver 0.0.0.0:8000

# 创建应用程序,确保和 manage.py 是同一目录
$ python manage.py startapp polls

# 运行创造模型变化迁移
$ python manage.py makemigrations

# 运行应用模型变化到数据库
$ python manage.py migrate

# admin创建管理员用户
$ python manage.py createsuperuser

注:自动重新加载 runserver,依照供给支付服务器自动重新加载Python代码为种种请求。您不要求重新起动服务器代码更改生效。不过,像添加文件有个别操作不接触重新启航,所以您没办法不再度开动在这几个情状下的服务器。

882828九五至尊手机版 3

 

MVC是举世著名的格局,即:将应用程序分解成三个组成都部队分:model(模型),view(视图),和
controller(控制 器)。当中:
     
M——管理应用程序的事态(平时存款和储蓄到数据库中),并约束改变状态的表现(恐怕叫做“业务规则”)。
     
C——接受外部用户的操作,依据操作访问模型获取数据,并调用“视图”展现这几个多少。控制器是将“模型”和“视图”隔开,并成为二者之间的联系难题。
      V——负责把数量格式化后突显给用户。

Django也是一个MVC框架。可是在Django中,控制器接受用户输入的局地由框架自行处理,所以
Django 里更关切的是模型(Model)、模板(Template)和视图(Views),称为
MTV形式:

    M 代表模型(Model),即数据存取层。 该层处理与数据有关的兼具事情:
如何存取、怎么样申明有效性、包含如何表现以及数据里面包车型地铁关联等。

    T 表示模板(Template),即表现层。 该层处理与表现有关的支配:
如何在页面或任何项目文书档案中举办展示。

    V 代表视图(View),即工作逻辑层。
该层包蕴存取模型及调取妥当模板的连锁逻辑。
你能够把它看做模型与模板之间的桥梁。

 

骨干目录结构及成效:

mysite/              # 项目的容器,名字随便起
    manage.py        # 命令行实用工具,以各种方式与该Django项目进行交互
    mysite/          # 实际的Python项目
        __init__.py  # 空文件,导入不出错
        settings.py  # 这个Django项目配置
        urls.py      # 这个Django项目的URL声明; 一个Django驱动网站的“目录”
        wsgi.py      # 一个入口点为WSGI兼容的Web服务器,以满足您的项目

 

贰 、 Django 基本配置

 ② 、配置文件

1. 创建django程序

  • 终点命令:django-admin startproject sitename
     (在当前目录下创办3个Django程序)
  • IDE创立Django程序时,本质上都以半自动执行上述命令

其余常用命令:

  python manage.py runserver ip:port
 (运营服务器,暗中同意ip和端口为http://127.0.0.1:8000/)

  python manage.py startapp appname  (新建 app)

  python manage.py syncdb  (同步数据库命令,Django
1.7及以上版本需求用以下的一声令下)

  python manage.py makemigrations  (展现并记录全数数据的变动)

  python manage.py migrate  (将转移更新到数据库)

  python manage.py createsuperuser  (成立一流管理员)

  python manage.py dbshell  (数据库命令行)

  python manage.py  (查看命令列表)

 

数据库

# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

# 如下设置放置的与project同名的配置的 __init__.py文件中

import pymysql
pymysql.install_as_MySQLdb() 

# 在settings 中修改DATABASES 

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',
    'USER': 'root',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

模板 

# 也在settings里修改,放html文件

TEMPLATE_DIRS = (
        os.path.join(BASE_DIR,'templates'),
    )

 静态文件

# 依然在settings里修改添加,放css,js等文件

STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'),
    )

 

2. 先后目录

882828九五至尊手机版 4

 

 三 、路由系统

3. 布局文件

1、URL 调度

二个完完全全,优雅的 ULANDL 方案是多个高品质的 Web 应用程序的贰个重中之重的底细。

tornado 分裂的是2个url 对应三个函数,而毫不3个类。

像是3个新华字典的目录,对应了 views 函数来进展处理,即那么些 url
要用有些钦点的 views 函数处理。

来看以下示例,怎么着动态构造:

from app1 import views

urlpatterns = [
    url(r'^manage1/(\d*)', views.manage1),
    url(r'^manage2/(?P<name>\w*)/(?P<id>\d*)', views.manage2),
    url(r'^manage3/(?P<name>\w*)', views.manage3,{'id':333}),
]

# 需要注意
# url多传了一个参数,那views函数得多接受一个参数 

882828九五至尊手机版 5882828九五至尊手机版 6

# 对应接收值

def manage1(request, age):
    print(age)        # 18
    return HttpResponse('1')

def manage2(request, name, id):
    print(name, id)     # nick 18
    return HttpResponse('2')

def manage3(request, name, id):
    print(name, id)     # nick 666
    return HttpResponse('3')

对应 views 函数接收值

 

二级路由: 那如果映射 url 太多怎么做,全写一个在  urlpatterns
显得繁琐,so 二级路由运用而生

# 一级路由规定 app1 开头的都去 app1.urls 中找
# 二级在详细规定对应 views 函数

# 一级
urlpatterns = [
    url(r'^app1/', include('app1.urls')),
]

# 二级
urlpatterns = [
    url(r'^1$', views.manage1),
]

 

a、数据库

支撑SQLite 3(暗许)、PostgreSQL 、MySQL、Oracle数据库的操作

882828九五至尊手机版 7882828九五至尊手机版 8

# 默认是SQLit 3 的配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# MySQL的配置

DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME':'dbname',   #注意这里的数据库应该以utf-8编码
    'USER': 'xxx',
    'PASSWORD': 'xxx',
    'HOST': '',
    'PORT': '',
    }
}

# 对于python3的使用者们还需要再加一步操作
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替

# 如下设置放置的与project同名的配置的 __init__.py文件中

import pymysql
pymysql.install_as_MySQLdb()


# PostgreSQL配置
DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'USER': 'XXX',
        'PASSWORD': 'XXX'
    }


# Oracle配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.oracle',
        'NAME': 'xe',
        'USER': 'a_user',
        'PASSWORD': 'a_password',
        'HOST': '',
        'PORT': '',
    }
}

具体安排

Django框架对于开发者而言中度透明化,对于差异数据库的具体选择办法是均等的,改变数据库类型只必要转移上述配置即可。

想要领会越多请戳那里

 

b、静态文件添加

882828九五至尊手机版 9882828九五至尊手机版 10

# 首先在项目根目录下创建static目录

# 接着在settings.py 文件下添加

STATIC_URL = '/static/'  # 默认已添加,使用静态文件时的前缀
STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'static'), #行末的逗号不能漏
    )

# 这样在template中就可以导入static目录下的静态文件啦

# 例:
<script src="/static/jquery-1.12.4.js"></script>

settings配置

 

② 、Django是何许处理3个伸手

当用户请求从你的 Django 的网站页面,那是该连串遵照以分明什么 Python
代码执行的算法:

  1. Django 请求是 U奔驰G级L 配置模块配置。平常经过值 ROOT_UPAJEROLCONF 设置,但万一传入 HttpRequest 对象拥有 urlconf 属性(由中间件设置),它的值将代表的可以选拔 ROOT_URLCONF 的设置。
  2. Django 的载荷是 Python 模块并物色变量 urlpatterns。那是1个 django.conf.urls.url() 实例。
  3. Django 的贯通每种 UCRUISERL 形式,从而,在所请求的 U帕杰罗L 匹配的率先个结束。
  4. 882828九五至尊手机版,要是某些正则表明式相匹配,就运营相对应的视图函数(或依据类的视图)。该视图被传送以下参数:
    • HttpRequest 对象。
    • 尽管协作的正则表明式没有再次来到命名组,然后从正则表明式比赛是作为职责参数。
    • 主要词参数是由由正则表达式匹配的别的命名组,由内定的可选参数的任何覆盖的 kwargs参数 django.conf.urls.url()。
  5. 假使没有正则表明式匹配,可能一旦四个老大在那么些进度中的任何一点时建议,Django的调用适当的错误处理视图。

 

叁 、 Django 路由系统

U汉兰达L配置(UCRUISERLconf)就好像Django
所协助网站的目录。它的精神是U大切诺基L方式以及要为该U途观L情势调用的视图函数之间的映射表;你正是以那种艺术告知Django,对于这些UGL450L调用这段代码,对于尤其UWranglerL调用那段代码。U揽胜极光L的加载是从配置文件中初露。

882828九五至尊手机版 11

参数表达:

  • 1个正则表达式字符串
  • 二个可调用对象,日常为3个视图函数或多个点名视图函数路径的字符串
  • 可选的要传送给视图函数的暗中认可参数(字典情势)
  • 一个可选的name参数

 

③ 、官方示例

1. 示例

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

说明:

  • 要捕获从UXC90L中的值,用括号括起来,会当参数字传送入 views 视图。
  • 从未供给添加1个斜线,因为各个UXC90L都有。例如,它^articles不是^/articles
  • 'r'方今的各类正则表达式字符串中是可选的,但提议。它报告Python字符串是“原始”
    -没有啥字符串中应当展开转义。

伸手示例:

  • 一个伸手 /articles/2005/03/ 会匹配上面列表中的第①条. Django
    会调用函数 views.month_archive(request, '2005', '03').
  • /articles/2005/3/ 不会合营下面列表中的任何条目,
    因为第贰条的月份必要几个人数字.
  • /articles/2003/ 会匹配上第壹条而不是第一条,因为门道相当是依据从上到下顺序而进行的,
    Django 会调用函数 views.special_case_2003(request)
  • /articles/2003 不会同盟下边列表中的任何条目, 因为各种U奥德赛L应该以 /
    结尾.
  • /articles/2003/03/03/ 会匹配上最终一条. Django
    会调用函数 views.article_detail(request, '2003', '03', '03').

1> 以下代码是官方示例:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]

 笔记注意事项:

  • 要捕获从U奇骏L中的值,用括号括起来,会当参数字传送入 views 视图。
  • 向来不供给添加二个斜线,因为每一个UOdysseyL都有。例如,它^articles不是^/articles
  • 'r'前面包车型客车每一个正则表明式字符串中是可选的,但提议。它告诉Python字符串是“原始”
    -没有何字符串中应当展开转义。

 比喻请求:

  • 请求 /articles/2005/03/将卓殊列表中的第二项。Django的将调用该函数 。views.month_archive(request,'2005', '03')
  • /articles/2005/3/  不会同盟任何 UKoleosL
    情势,因为在列表中的第一项中必要两位数字的月份。
  • /articles/2003/将分外的列表,而不是第①个第贰美术,因为该图案,以便测试,第三个是在率先测试通过。随意行使顺序插入特殊情状是那般的。在此地,Django的将调用该函数 views.special_case_2003(request)
  • /articles/2003 不包容任何那一个方式,因为每一种格局须求 UHavalL
    以斜线截至。
  • /articles/2003/03/03/将匹配的结尾格局。Django
    的将调用该函数。views.article_detail(request,'2003', '03', '03')

 

 

 2> 命名组

上面的例子使用了简便易行的,非命名的正则表明式组(通过括号)来捕获 U奥迪Q7L
的位,并通过他们的职位参数的视图。在更尖端的用法,它能够利用命名 正则表明式组来捕获
U讴歌ZDXL 位,将它们作为重点字参数字传送递给视图。

 在 Python
正则表明式
,命名正则表明式组的语法(?P<name>pattern),这里 name是组的称谓, pattern尽管某种情势相匹配。

 下边是地点的事例中的U路虎极光Lconf,改写使用命名组:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

那刚刚完毕同样的业务,前面包车型大巴例证,2个微小的出入:捕获的值传递给查看功用作为主要字参数,而不是岗位参数。例如:

  • 请求/articles/2005/03/会调用函数来代替,views.month_archive(request, year='2005',month='03')``views.month_archive(request, '2005', '03')
  • 请求/articles/2003/03/03/会调用该函数,views.article_detail(request, year='2003',month='03', day='03')

在实践中,那意味你的 UTiguanLconf 稍微更引人侧目,不简单参数顺序错误 –
你能够在你的眼光’函数定义再次排序的参数。当然,那么些亮点来在简易的费用; 一些开支义务命名组的语法丑陋,太冗长。

2. 命名组(Named groups)

在上头的简单例子中,并不曾应用正则表明式分组,在更尖端的用法中,很有或然使用正则分组来匹配U陆风X8L并且将分组值通过参数字传送递给view函数。

在Python的正则表明式中,分组的语法是 (?P<name>pattern),
name代表分组名,pattern表示一些万分正则.

此地是二个简短的小例子:

# 正则知识
import re

ret=re.search('(?P<id>\d{3})/(?P<name>\w{3})','weeew34ttt123/ooo')

print(ret.group())
print(ret.group('id'))
print(ret.group('name'))
-------------------------------------
123/ooo
123
ooo

  

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
]

For example:

  • A request
    to /articles/2005/03/ 会调用函数 views.month_archive(request, year='2005',month='03'),
    而不是 views.month_archive(request, '2005', '03').
  • A request
    to /articles/2003/03/03/ 会调用函数 views.article_detail(request, year='2003',month='03', day='03').

广大写法实例:

882828九五至尊手机版 12

合营/分组算法

那里的U奥迪Q5L配置解析器服从算法,相对李碧华则表明式命名组与非命名组:

  1. 假使有其余命名参数,它会选拔那么些,而忽略非命名参数。
  2. 要不,它会由此拥有非命名参数作为任务参数。

在那二种情状下,被给予按其余附加的重中之重字参数字传送递额外的选项来查看效率也将被传送给视图

 

 

3> What the URLconf searches against

The URLconf searches against the requested URL, as a normal Python
string. This does not include GET or POST parameters, or the domain
name.

For example, in a request to https://www.example.com/myapp/, the
URLconf will look for myapp/.

In a request to https://www.example.com/myapp/?page=3, the URLconf
will look for myapp/.

该URubiconL配置不看请求方法。换言之,全体的呼吁的办法,GET,POST“ 等将被路由到为同样的U本田CR-VL,相同的效用。

 

3. 二级路由(Including)

那假如映射 url 太多怎么做,全写叁个在  urlpatterns 显得繁琐,so
二级路由运用而生

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]

urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]

在上头这些事例中,尽管请求url为 /credit/reports/ 则会调用函数 credit_views.report().

 

使用二级路由也能够减去代码冗余,使代码特别简明易懂

# 原始版本
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/history/$', views.history),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/edit/$', views.edit),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/discuss/$', views.discuss),
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]


# 改进版本
from django.conf.urls import include, url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]

  

4> 捕获的参数总是字符串

每种捕获的参数发送到视图作为普通的 Python
字符串,无论什么样的协作正则表明式匹配。

例如,在该URL配置行:

url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),

…的 year参数字传送递给 views.year_archive()将是2个字符串,

不是二个整数,固然 [0-9]{4}将只匹配整数字符串。

 

4. 添加额外的参数

UCRUISERLconfs 有3个钩子能够让您进入一些拾分的参数到view函数中.

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在上头的例子中,若是三个伸手为 /blog/2005/, Django
将会调用函数l views.year_archive(request, year='2005',foo='bar').

亟待专注的是,当您加上参数时,对应函数views.year_archive必须抬高贰个参数,参数名也非得命名为
foo,如下:

 

def year_archive(request, foo):
    print(foo)
    return render(request, 'index.html')

  

5> 钦定view的暗中认可设置

 一个利于的技能是您的视角的实证钦命默许参数。上面是贰个事例的 RubiconLconf 和理念:

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

在上述的例证中,八个 UKoleosL
形式指向同一个视图 views.page但第壹图案不抓获从 URL
任何事物。借使第几个形式匹配,该 page()函数将应用它的私下认可参数 num"1"。固然第1图案相匹配时, page()将选用别的 num值由正则表明式捕获。

 

5. 别名的使用

url(r'^index',views.index,name='bieming')

url中还帮助name参数的安插,假如安插了name属性,在模板的文件中就能够运用name值来代表相应的url值.

咱俩来看3个事例:

882828九五至尊手机版 13882828九五至尊手机版 14

urlpatterns = [
    url(r'^index',views.index,name='bieming'),
    url(r'^admin/', admin.site.urls),
    # url(r'^articles/2003/$', views.special_case_2003),
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    # url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),

]
###################

def index(req):
    if req.method=='POST':
        username=req.POST.get('username')
        password=req.POST.get('password')
        if username=='alex' and password=='123':
            return HttpResponse("登陆成功")



    return render(req,'index.html')

#####################

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
{#     这里只要使用bieming即可代替/index #}
     <form action="{% url 'bieming' %}" method="post">
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>


#######################

name的应用

  

 6> 包蕴此外的ULANDLconf 

在其它时候,你urlpatterns能够“include”其他的U大切诺基Lconf模块。那实质上是“roots”的一套低于其余的网址。

譬如,那里的U帕杰罗L配置为节选的Django网站 自个儿。它包含过多其余的UTiguanLconf的:

from django.conf.urls import include, url

urlpatterns = [
    # ... snip ...
    url(r'^community/', include('django_website.aggregator.urls')),
    url(r'^contact/', include('django_website.contact.urls')),
    # ... snip ...
]

请留意,在那一个例子中,正则表达式没有三个$ (截至字符串匹配字符),但包括尾随斜线。每当 Django 的遇到 include()django.conf.urls.include()),它扒关闭其余匹配到该点的USportageL的一局地,并将剩余的字符串所富含的UCR-VL配置用于进一步的拍卖。

另一种只怕是因此选取的列表,以囊括此外的网址格式
 url()实例。例如,考虑那几个 U凯雷德L 配置:

from django.conf.urls import include, url

from apps.main import views as main_views
from credit import views as credit_views

extra_patterns = [
    url(r'^reports/$', credit_views.report),
    url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
    url(r'^charge/$', credit_views.charge),
]

urlpatterns = [
    url(r'^$', main_views.homepage),
    url(r'^help/', include('apps.help.urls')),
    url(r'^credit/', include(extra_patterns)),
]

在这些例子中,/credit/reports/U揽胜L将被拍卖 credit_views.report()的Django图。

从里面单个图案前缀被重复使用的U库罗德Lconf去除冗余。

咱俩得以因此注脚的一起路径前缀只有一遍,分组,例如那个U安德拉L配置:

from django.conf.urls import include, url
from . import views

urlpatterns = [
    url(r'^(?P<page_slug>[\w-]+)-(?P<page_id>\w+)/', include([
        url(r'^history/$', views.history),
        url(r'^edit/$', views.edit),
        url(r'^discuss/$', views.discuss),
        url(r'^permissions/$', views.permissions),
    ])),
]

6. 钦赐view的暗许配置

# URLconf
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^blog/$', views.page),
    url(r'^blog/page(?P<num>[0-9]+)/$', views.page),
]

# View (in blog/views.py)
def page(request, num="1"):
    # Output the appropriate page of blog entries, according to num.
    ...

在上述的例子中,八个 UXC90L
格局指向同2个视图 views.page但第二图案不抓获从 UTiggoL
任何事物。假诺第3个方式匹配,该 page()函数将采用它的私下认可参数 num"1"。如若第叁图案相匹配时, page()将采取其他 num值由正则表达式捕获。

 

 

肆 、 Django Views(视图函数)

http请求中发出多个主导指标:

  http请求:HttpRequest对象

  http响应:HttpResponse对象

 

7> 传递额外的选项来查阅效能

UOdysseyLconf
有三个关联,能够传递额外的参数给您的视图效率,作为一个 Python
字典。

django.conf.urls.url()效率能够应用那应当是外加的参数的字典传递给视图成效可选的第七个参数。

例如:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]

在这么些例子中,用于向请求/blog/2005/,Django会调用 。views.year_archive(request, year='2005',foo='bar')

# 处理冲突

这可能有它可以捕获一个名为关键字参数的URL模式,并且还传递参数,在其额外的参数字典相同的名称。发生这种情况时,在字典中的参数将被用来代替在URL捕获的参数。

1. HttpRequest对象

当呼吁叁个页面时,Django
创制三个 HttpRequest对象涵盖原数据的乞求。然后 Django
加载适当的视图,通过 HttpRequest用作视图函数的第叁个参数。各样视图负责重回多少个HttpResponse目标。

882828九五至尊手机版 15882828九五至尊手机版 16

path:       请求页面的全路径,不包括域名

method:     请求中使用的HTTP方法的字符串表示。全大写表示。例如

                   if  req.method=="GET":

                             do_something()

                   elseif req.method=="POST":

                             do_something_else()

GET:         包含所有HTTP GET参数的类字典对象

POST:       包含所有HTTP POST参数的类字典对象

             服务器收到空的POST请求的情况也是可能发生的,也就是说,表单form通过
             HTTP POST方法提交请求,但是表单中可能没有数据,因此不能使用
             if req.POST来判断是否使用了HTTP POST 方法;应该使用  if req.method=="POST"



COOKIES:     包含所有cookies的标准Python字典对象;keys和values都是字符串。

FILES:      包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中 
            name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:

            filename:      上传文件名,用字符串表示
            content_type:   上传文件的Content Type
            content:       上传文件的原始内容


user:       是一个django.contrib.auth.models.User对象,代表当前登陆的用户。如果访问用户当前
             没有登陆,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。你
             可以通过user的is_authenticated()方法来辨别用户是否登陆:
             if req.user.is_authenticated();只有激活Django中的AuthenticationMiddleware
             时该属性才可用

session:    唯一可读写的属性,代表当前会话的字典对象;自己有激活Django中的session支持时该属性才可用。

META:       一个标准的Python字典包含所有可用的HTTP头。可用标题取决于客户端和服务器,但这里是一些例子:

            CONTENT_LENGTH       – 请求体的长度(一个字符串)。
            CONTENT_TYPE         – 请求体的类型。
            HTTP_ACCEPT          - 为响应–可以接受的内容类型。
            HTTP_ACCEPT_ENCODING – 接受编码的响应
            HTTP_ACCEPT_LANGUAGE – 接受语言的反应
            HTTP_HOST            – 客户端发送的HTTP主机头。
            HTTP_REFERER         – 参考页面
            HTTP_USER_AGENT      – 客户端的用户代理字符串。
            QUERY_STRING         – 查询字符串,作为一个单一的(分析的)字符串。
            REMOTE_ADDR          – 客户端的IP地址
            REMOTE_HOST          – 客户端的主机名
            REMOTE_USER          – 用户通过Web服务器的身份验证。
            REQUEST_METHOD       – 字符串,如"GET"或"POST"
            SERVER_NAME          – 服务器的主机名
            SERVER_PORT          – 服务器的端口(一个字符串)。

HttpRequest对象属性

 

传送额外的选项来 include()

无差异于,您能够由此额外的挑选include()。当你通过额外的接纳include()每个中所包括的U哈弗L配置线将通过额外的选项。

比如,那四个U奇骏L配置集在效益上是一模一样的:

# 设置一个:

# main.py
from django.conf.urls import include, url

urlpatterns = [
    url(r'^blog/', include('inner'), {'blogid': 3}),
]

# inner.py
from django.conf.urls import url
from mysite import views

urlpatterns = [
    url(r'^archive/$', views.archive),
    url(r'^about/$', views.about),
]

# 设置两个

# main.py
from django.conf.urls import include, url
from mysite import views

urlpatterns = [
    url(r'^blog/', include('inner')),
]

# inner.py
from django.conf.urls import url

urlpatterns = [
    url(r'^archive/$', views.archive, {'blogid': 3}),
    url(r'^about/$', views.about, {'blogid': 3}),
]

 

 

2. HttpResponse对象

对于HttpRequest对象的话,是由django自动创造的,不过,HttpResponse对象就亟须大家和好创立。各种view请求处理办法必须回到三个HttpResponse对象。

在HttpResponse对象上增加的常用方法:

  • 页面渲染:render(推荐),render_to_response,
  • 页面跳转:redirect
  • locals:   能够直接将对应视图函数中存有的变量传给模板    

882828九五至尊手机版 17

值得注意的是对此页面渲染的点子中,render和render_to_response使用方法和效应类似,不过render效能更为强劲,推荐应用

四、视图层

对逻辑负责处理用户的请求并再次来到响应。反回能够是HTML内容的网页,或重定向,或404荒谬,或2个XML文件,或二个形象……此代码能够住在其他你想去的地点,只要它在你的Python路径。

在一个文件中称将视图views.py,放在你的品种或应用程序目录。

 

 壹 、重回火速效能

3. render()

render(requesttemplate_namecontext=Nonecontent_type=Nonestatus=Noneusing=None)[source]

组合给定的沙盘与三个加以的上下文,重临一个字典HttpResponse在渲染文本对象

render()

render(requesttemplate_namecontext=Nonecontent_type=Nonestatus=Noneusing=None)[source]

结缘给定的模版与一个加以的上下文,再次回到二个字典HttpResponse在渲染文本对象

所需的参数

 template_name 1个模板的采取或模板类别名称全称。借使体系是给定的,存在于第几个模板将被选用。

所需的参数

 template_name 三个模板的利用或模板连串名称全称。假诺系列是给定的,存在于第多少个模板将被运用。

可选参数

context    一组字典的值添加到模板中。私下认可情状下,那是二个空的字典。

content_type    MIME类型用于转移文书档案。

status    为响应状态代码。私下认可值为200

using    这一个名字1个模板引擎的使用将模板。

882828九五至尊手机版 18882828九五至尊手机版 19

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

render示例

可选参数

context    一组字典的值添加到模板中。暗中认可意况下,那是二个空的字典。

content_type    MIME类型用于转移文书档案。

status    为响应状态代码。暗中同意值为200

using    那么些名字二个模板引擎的施用将模板。

 

例子

from django.shortcuts import render

def my_view(request):
    # View code here...
    return render(request, 'myapp/index.html', {
        'foo': 'bar',
    }, content_type='application/xhtml+xml')

等价于

from django.http import HttpResponse
from django.template import loader

def my_view(request):
    # View code here...
    t = loader.get_template('myapp/index.html')
    c = {'foo': 'bar'}
    return HttpResponse(t.render(c, request), content_type='application/xhtml+xml')

 

 

五、 模板

render_to_response()

 render_to_response(template_namecontext=Nonecontent_type=Nonestatus=Noneusing=None)[source]

 这一个和  render() 大致,不引进,在现在只怕丢掉掉

 

1. 模板的实践

模版的制造进程,对于模版,其实就是读取模版(在那之中嵌套着沙盘标签),然后将
Model 中收获的多寡插入到模版中,最终将消息再次来到给用户。

882828九五至尊手机版 20882828九五至尊手机版 21

# view.py

def index(request):
    return render(request, 'index.html', {'title':'welcome'})


# index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <div>
        <h1>{{ title }}</h1>
    </div>

</body>
</html>

示例

 

redirect()

 redirect(topermanent=False\args**kwargs*)[source]

 暗中同意情况下,为权且重定向;通过 permanent=True安装永久重定向

def my_view(request):
    ...
    return redirect('/some/url/')


def my_view(request):
    ...
    object = MyModel.objects.get(...)
    return redirect(object, permanent=True)

 

2.  模板语言

模板中也有协调的语言,该语言能够兑现多少显示

  • {{ item }}
  • {% for item in item_list %}  <a>{{ item }}</a>  {%
    endfor %}
      forloop.counter
      forloop.first
      forloop.last 
  • {% if ordered_warranty %}  {% else %} {% endif %}
  • 母板:{% block title %}{% endblock %}
    子板:{% extends “base.html” %}
       {% block title %}{% endblock %}
  • 赞助方法:
    {{ item.event_start|date:”Y-m-d H:i:s”}}
    {{ bio|truncatewords:”30″ }}
    {{ my_list|first|upper }}
    {{ name|lower }}

 小知识点:在模板语言中字典数据类型的取值是透过dict.xxx而不是dict[xxx]

 二 、求和响应对象

Django 使用请求和响应对象在系统间传递状态。

当呼吁3个页面时,Django
创立二个 HttpRequest对象涵盖原数据的乞请。然后 Django
加载适当的视图,通过 HttpRequest用作视图函数的第二个参数。每种视图负责再次来到二个HttpResponse目标。

 

HttpRequest对象

HttpRequest.scheme 

一个字符串表示请求的方案(HTTP或HTTPS)通常

HttpRequest.path

一个字符串的完整路径的请求

HttpRequest.method

请求的HTTP方法。这是保证要大写

if request.method == ‘GET’:
do_something()
elif request.method == ‘POST’:
do_something_else()

HttpRequest.GET

字典像包含所有给定的HTTP GET参数对象。

HttpRequest.POST

字典像包含所有给定的HTTP POST参数对象,提供请求包含表单数据。

HttpRequest.COOKIES

一个标准的Python字典,包含了所有的COOKIES,key和values都是字符串

HttpRequest.FILES

字典像对象包含所有上传的文件。
html 标签 <input type="file" name="" />

filename # 上传的公文名
content_type # 上传文件的花色
content # 上传文件的始末

HttpRequest.META

一个标准的Python字典包含所有可用的HTTP头。可用标题取决于客户端和服务器,但这里是一些例子:

CONTENT_LENGTH – 请求体的长短(四个字符串)。
CONTENT_TYPE – 请求体的项目。
HTTP_ACCEPT – 为响应–能够承受的内容类型。
HTTP_ACCEPT_ENCODING – 接受编码的响应
HTTP_ACCEPT_LANGUAGE – 接受语言的感应
HTTP_HOST – 客户端发送的HTTP主机头。
HTTP_REFERE景逸SUV – 参考页面
HTTP_USER_AGENT – 客户端的用户代理字符串。
QUE凯雷德Y_ST兰德HavalING – 查询字符串,作为二个纯粹的(分析的)字符串。
REMOTE_ADDCRUISER – 客户端的IP地址
REMOTE_HOST – 客户端的主机名
REMOTE_USE奥迪Q5 – 用户通过Web服务器的身份验证。
REQUEST_METHOD – 字符串,如”GET”或”POST”
SERVER_NAME – 服务器的主机名
SE昂CoraVERAV4_PORubiconT – 服务器的端口(一个字符串)。

 

3. 自定义标签

因为在模板语言中不可见做运算等片段稍显复杂的操作,所以在Django中提供了三种自定制标签,一种是simple_tag,一种是filter。

simple_tag: 任意传递参数,可是无法用作布尔判断

filter: 最八只好传递一个参数,能够看做布尔判断

在此处根本介绍simple_tag类型,filter的兑现类似

a、在app中创建templatetags模块

b、创造任意 .py 文件,如:xx.py

882828九五至尊手机版 22882828九五至尊手机版 23

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3

@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

示例

c、在运用自定义simple_tag的html文件中程导弹入在此之前创造的 xx.py 文件名

{% load xx %}

d、使用simple_tag

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

e、在settings中配置当前app,不然django不只怕找到自定义的simple_tag

882828九五至尊手机版 24882828九五至尊手机版 25

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
)

示例

越多见文书档案:https://docs.djangoproject.com/en/1.10/ref/templates/language/

 

HttpResponse对象

 对于HttpRequest 对象的话,是由django自动创设的,可是,HttpResponse
对象就必须大家协调创建。每一种 view 请求处理办法必须回到3个 HttpResponse
对象。

HttpResponse 类在 django.http.HttpResponse

六、 Model

Django提供了一个抽象层(“Model”)来营造和管理Web应用程序的多寡。

django中遵守 Code Frist
的尺度,即:依照代码中定义的类来自动生成数据库表。

论及对象映射(Object Relational Mapping,简称OLacrosseM)。

 

 字符串使用:

卓绝的用法是通过页面包车型客车内容,为一个字符串

>>> from django.http import HttpResponse
>>> response = HttpResponse("Here's the text of the Web page.")
>>> response = HttpResponse("Text only, please.", content_type="text/plain")

# 如果你想添加内容的增量
>>> response = HttpResponse()
>>> response.write("<p>Here's the text of the Web page.</p>")
>>> response.write("<p>Here's another paragraph.</p>")

1. 创建表

a、基本组织

from django.db import models

 class userinfo(models.Model):
    name = models.CharField(max_length=30)
    email = models.EmailField()
    memo = models.TextField()

882828九五至尊手机版 26882828九五至尊手机版 27

1、null=True
  数据库中字段是否可以为空
2、blank=True
  django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
  auto_now   自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add  自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
        (u'M', u'Male'),
        (u'F', u'Female'),
    )
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column  数据库中的字段名称
10、unique=True  不允许重复
11、db_index = True  数据库索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[]
17、upload-to

越多参数

882828九五至尊手机版 28882828九五至尊手机版 29

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制
23、models.ImageField   图片
24、models.FilePathField 文件

更多字段

882828九五至尊手机版 30882828九五至尊手机版 31

class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"

            # 联合索引
            index_together = [
                ("pub_date", "deadline"),
            ]

            # 联合唯一索引
            unique_together = (("driver", "restaurant"),)

            # admin中显示的表名称
            verbose_name

            # verbose_name加s
            verbose_name_plural

    更多:https://docs.djangoproject.com/en/1.10/ref/models/options/

元信息

882828九五至尊手机版 32882828九五至尊手机版 33

1.触发Model中的验证和错误提示有两种方式:
        a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
        b. 调用Model对象的 clean_fields 方法,如:
            # models.py
            class UserInfo(models.Model):
                nid = models.AutoField(primary_key=True)
                username = models.CharField(max_length=32)

                email = models.EmailField(error_messages={'invalid': '格式错了.'})

            # views.py
            def index(request):
                obj = models.UserInfo(username='11234', email='uu')
                try:
                    print(obj.clean_fields())
                except Exception as e:
                    print(e)
                return HttpResponse('ok')

           # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。

    2.Admin中修改错误提示
        # admin.py
        from django.contrib import admin
        from model_club import models
        from django import forms


        class UserInfoForm(forms.ModelForm):
            username = forms.CharField(error_messages={'required': '用户名不能为空.'})
            email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'})
            age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'})

            class Meta:
                model = models.UserInfo
                # fields = ('username',)
                fields = "__all__"


        class UserInfoAdmin(admin.ModelAdmin):
            form = UserInfoForm


        admin.site.register(models.UserInfo, UserInfoAdmin)

展开文化

 

b、连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

行使场景:

  • 一对多:当一张表中创设一行数据时,有三个单选的下拉框(能够被再次采用)
    譬如说:创设用户音信时候,必要选取四个用户类型【普通用户】【金牌用户】【铂金用户】等。
  • 多对多:在某表中开创一行数据是,有二个足以多选的下拉框
    比如:创造用户音信,须要为用户内定八个爱好
  • 13分:在某表中创立一行数据时,有1个单选的下拉框(下拉框中的内容被用过一遍就消失了
    例如:原有含10列数据的一张表保存有关消息,经过一段时间之后,10列不或许知足必要,要求为原本的表再添加5列数据

882828九五至尊手机版 34882828九五至尊手机版 35

ForeignKey(ForeignObject) # ForeignObject(RelatedField)
to,                         # 要进行关联的表名
to_field=None,              # 要关联的表中的字段名称
on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为
- models.CASCADE,删除关联数据,与之关联也删除
- models.DO_NOTHING,删除关联数据,引发错误IntegrityError
- models.PROTECT,删除关联数据,引发错误ProtectedError
- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
- models.SET,删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

def func():
    return 10

class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id"
    on_delete=models.SET(func),)
related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
db_constraint=True          # 是否在数据库中创建外键约束
parent_link=False           # 在Admin中是否显示关联数据


OneToOneField(ForeignKey)
to,                         # 要进行关联的表名
to_field=None               # 要关联的表中的字段名称
on_delete=None,             # 当删除关联表中的数据时,当前表与其关联的行的行为

###### 对于一对一 ######
# 1. 一对一其实就是 一对多 + 唯一索引
# 2.当两个类之间有继承关系时,默认会创建一个一对一字段
# 如下会在A表中额外增加一个c_ptr_id列且唯一:
class C(models.Model):
    nid = models.AutoField(primary_key=True)
    part = models.CharField(max_length=12)

class A(C):
    id = models.AutoField(primary_key=True)
    code = models.CharField(max_length=1)

ManyToManyField(RelatedField)
to,                         # 要进行关联的表名
related_name=None,          # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()
related_query_name=None,    # 反向操作时,使用的连接前缀,用于替换【表名】     如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')
limit_choices_to=None,      # 在Admin或ModelForm中显示关联数据时,提供的条件:
# 如:
- limit_choices_to={'nid__gt': 5}
- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q
- limit_choices_to=Q(nid__gt=10)
- limit_choices_to=Q(nid=8) | Q(nid__gt=10)
- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
symmetrical=None,           # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段
# 做如下操作时,不同的symmetrical会有不同的可选字段
models.BB.objects.filter(...)

# 可选字段有:code, id, m1
class BB(models.Model):

code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=True)

# 可选字段有: bb, code, id, m1
class BB(models.Model):

code = models.CharField(max_length=12)
m1 = models.ManyToManyField('self',symmetrical=False)

through=None,               # 自定义第三张表时,使用字段用于指定关系表
through_fields=None,        # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=50)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(
        Person,
        through='Membership',
        through_fields=('group', 'person'),
    )

class Membership(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    inviter = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name="membership_invites",
    )
    invite_reason = models.CharField(max_length=64)
db_constraint=True,         # 是否在数据库中创建外键约束
db_table=None,              # 默认创建第三张表时,数据库中表的名称

字段以及参数

 

特点与措施:

HttpResponse.content

一个bytestring代表内容

 HttpResponse.charset

一个字符串的字符集表示的响应将编码

HttpResponse.status_code

HTTP状态代码为响应码

HttpResponse.streaming

这个属性永远为假,一般用于中间件

HttpResponse.closed

关闭

 

方法:

HttpResponse.__init__(content=”, content_type=None, status=200,
reason=None, charset=None)[source]

实例化类自动执行的方法

HttpResponse.__setitem__(header, value)

为给定值给定的标题名称。都是字符串

HttpResponse.__delitem__(header)

删除标题的名称。不区分大小写。

HttpResponse.__getitem__(header)

获取给定标题名称。不区分大小写。

HttpResponse.has_header(header)

检查是否具有给定名称的一个标题

HttpResponse.setdefault(header, value)

设置一个标题,除非它已经设置。

HttpResponse.set_cookie(key, value=”, max_age=None, expires=None,
path=’/’, domain=None, secure=None, httponly=False)

设置一个cookie。参数跟标准库的Cookie对象差不多

HttpResponse.set_signed_cookie(key, value, salt=”, max_age=None,
expires=None, path=’/’, domain=None, secure=None, httponly=True)

加密cookice,可以用 HttpRequest.get_signed_cookie() 获取,当然你也可以加盐

HttpResponse.delete_cookie(key, path=’/’, domain=None)

删除Cookie与给定键。

 

HttpResponse子类:

class HttpResponseRedirect[source]

构造函数的第一个参数是必需的–路径redirectto。这是一个完全合格的URL(例如“https://www.yahoo.com /搜索/),没有一个绝对的路径(例如域搜索/ /),甚至是相对路径(如“/”)。在最后的情况下,客户端浏览器将重建完整的URL本身的电流路径。看到HttpResponse其他optionalconstructor参数。请注意,这将返回一个HTTP状态代码302。

class HttpResponsePermanentRedirect[source]

像httpresponseredirect,但它返回一个永久重定向(HTTP状态代码301)而不是“发现”的重定向(状态代码302)

class HttpResponseNotModified[source]

构造函数不带任何参数和NO含量应该被添加到这一反应。使用指定一个页面没有被modifiedsince用户的最后一个请求(状态代码304)。

class HttpResponseBadRequest[source]

就像HttpResponse但使用400状态码

class HttpResponseNotFound[source]

就像HttpResponse但使用404状态码

class HttpResponseForbidden[source]

就像HttpResponse但使用403状态码

class HttpResponseNotAllowed[source]

像HttpResponse,但使用405状态码。第一argumentto构造函数要求准许清单的方法(如(get,后])

class HttpResponseGone[source]

就像HttpResponse但使用410状态码

class HttpResponseServerError[source]

就像HttpResponse但使用500状态码

 

 

2. 操作表

a、基本操作

882828九五至尊手机版 36882828九五至尊手机版 37

# 增
    #
    # models.Tb1.objects.create(c1='xx', c2='oo')  增加一条数据,可以接受字典类型数据 **kwargs

    # obj = models.Tb1(c1='xx', c2='oo')
    # obj.save()

    # 查
    #
    # models.Tb1.objects.get(id=123)         # 获取单条数据,不存在则报错(不建议)
    # models.Tb1.objects.all()               # 获取全部
    # models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

    # 删
    #
    # models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

    # 改
    # models.Tb1.objects.filter(name='seven').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs
    # obj = models.Tb1.objects.get(id=1)
    # obj.c1 = '111'
    # obj.save()                                                 # 修改单条数据

基本操作

 

b、进阶操作(了不起的双下划线)

运用双下划线将字段和呼应的操作连接起来

882828九五至尊手机版 38882828九五至尊手机版 39

# 获取个数
        #
        # models.Tb1.objects.filter(name='seven').count()

        # 大于,小于
        #
        # models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
        # models.Tb1.objects.filter(id__gte=1)              # 获取id大于等于1的值
        # models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lte=10)             # 获取id小于10的值
        # models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

        # in
        #
        # models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
        # models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

        # isnull
        # Entry.objects.filter(pub_date__isnull=True)

        # contains
        #
        # models.Tb1.objects.filter(name__contains="ven")
        # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
        # models.Tb1.objects.exclude(name__icontains="ven")

        # range
        #
        # models.Tb1.objects.filter(id__range=[1, 2])   # 范围bettwen and

        # 其他类似
        #
        # startswith,istartswith, endswith, iendswith,

        # order by
        #
        # models.Tb1.objects.filter(name='seven').order_by('id')    # asc
        # models.Tb1.objects.filter(name='seven').order_by('-id')   # desc

        # group by
        #
        # from django.db.models import Count, Min, Max, Sum
        # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
        # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

        # limit 、offset
        #
        # models.Tb1.objects.all()[10:20]

        # regex正则匹配,iregex 不区分大小写
        #
        # Entry.objects.get(title__regex=r'^(An?|The) +')
        # Entry.objects.get(title__iregex=r'^(an?|the) +')

        # date
        #
        # Entry.objects.filter(pub_date__date=datetime.date(2005, 1, 1))
        # Entry.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1))

        # year
        #
        # Entry.objects.filter(pub_date__year=2005)
        # Entry.objects.filter(pub_date__year__gte=2005)

        # month
        #
        # Entry.objects.filter(pub_date__month=12)
        # Entry.objects.filter(pub_date__month__gte=6)

        # day
        #
        # Entry.objects.filter(pub_date__day=3)
        # Entry.objects.filter(pub_date__day__gte=3)

        # week_day
        #
        # Entry.objects.filter(pub_date__week_day=2)
        # Entry.objects.filter(pub_date__week_day__gte=2)

        # hour
        #
        # Event.objects.filter(timestamp__hour=23)
        # Event.objects.filter(time__hour=5)
        # Event.objects.filter(timestamp__hour__gte=12)

        # minute
        #
        # Event.objects.filter(timestamp__minute=29)
        # Event.objects.filter(time__minute=46)
        # Event.objects.filter(timestamp__minute__gte=29)

        # second
        #
        # Event.objects.filter(timestamp__second=31)
        # Event.objects.filter(time__second=2)
        # Event.objects.filter(timestamp__second__gte=31)

进阶操作

 

c、其他操作

882828九五至尊手机版 40882828九五至尊手机版 41

# extra
    #
    # extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None)
    #    Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,))
    #    Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
    #    Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"])
    #    Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, select_params=(1,), order_by=['-nid'])

    # F
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)


    # Q
    #
    # 方式一:
    # Q(nid__gt=10)
    # Q(nid=8) | Q(nid__gt=10)
    # Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
    # 方式二:
    # con = Q()
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)


    # 执行原生SQL
    #
    # from django.db import connection, connections
    # cursor = connection.cursor()  # cursor = connections['default'].cursor()
    # cursor.execute("""SELECT * from auth_user where id = %s""", [1])
    # row = cursor.fetchone()

任何操作

 

d、连表操作(了不起的双下划线)

运用双下划线和 _set
将表之间的操作连接起来

882828九五至尊手机版 42882828九五至尊手机版 43

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username


class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name


class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption


class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

表结构实例

882828九五至尊手机版 44882828九五至尊手机版 45

user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()

一对一操作

882828九五至尊手机版 46882828九五至尊手机版 47

# 添加一对多
    dic = {
        "hostname": "名字1",
        "ip": "192.168.1.1",
        "user_group_id": 1,   # 加对象则为"user_group"
    }
    models.Host.objects.create(**dic)

    # 正向查一对多
    host_obj = models.Host.objects.all()
    print(type(host_obj),     # <class 'django.db.models.query.QuerySet'>
          host_obj)           # <QuerySet [<Host: 名字1>]>
    for item in host_obj:
        print(item.hostname)
        print(item.user_group.caption)
        print(item.user_group.user_info.values())
        # <QuerySet [{'name': 'nick', 'user_type': 1, 'id': 1, 'email': '630571017@qq.com', 'address': '128号'}]>

    usergroup_obj = models.Host.objects.filter(user_group__caption='标题1')
    print(usergroup_obj)


    # 反向查一对多
    usergroup_obj = models.UserGroup.objects.get(id=1)
    print(usergroup_obj.caption)
    ret = usergroup_obj.host_set.all()  # 所有关于id=1的host
    print(ret)

    obj = models.UserGroup.objects.filter(host__ip='192.168.1.1').\
        values('host__id', 'host__hostname')
    print(obj)      # <QuerySet [{'host__id': 1, 'host__hostname': '名字1'}]>

一对多

882828九五至尊手机版 48882828九五至尊手机版 49

user_info_obj = models.UserInfo.objects.get(name='nick')
user_info_objs = models.UserInfo.objects.all()

group_obj = models.UserGroup.objects.get(caption='CTO')
group_objs = models.UserGroup.objects.all()

# 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)

# 删除数据
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)

# 添加数据
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)

# 删除数据
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)

# 获取数据
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)

# 获取数据
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CTO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')

    # 添加多对多
    # userinfo_id_1 = models.UserInfo.objects.filter(id=1)
    # usergroup_id_1 = models.UserGroup.objects.filter(id=1).first()
    # usergroup_id_1.user_info.add(*userinfo_id_1)

多对多操作

 

五、模板层

  作为2个Web框架,Django 须要模板。模板包括所需的 HTML
输出静态部分以及动态内容插入。

扩展:

① 、模版的执行

882828九五至尊手机版 50882828九五至尊手机版 51

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

from django import template
t = template.Template('My name is {{ name }}.')
c = template.Context({'name': 'Adrian'})
print t.render(c)

import datetime
from django import template
import DjangoDemo.settings

now = datetime.datetime.now()
fp = open(settings.BASE_DIR+'/templates/Home/Index.html')
t = template.Template(fp.read())
fp.close()
html = t.render(template.Context({'current_date': now}))
return HttpResponse(html

from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    t = get_template('current_datetime.html')
    html = t.render(Context({'current_date': now}))
    return HttpResponse(html)

return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))

示例

 

a、自定义上传

882828九五至尊手机版 52882828九五至尊手机版 53

def upload_file(request):
    if request.method == "POST":
        obj = request.FILES.get('fafafa')
        f = open(obj.name, 'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
    return render(request, 'file.html')

示例

② 、模版语言

 模板中也有友好的言语,该语言可以兑现数据展示

  • {{ item }}
  • {% for item in item_list %}  <a>{{ item }}</a>  {%
    endfor %}
      forloop.counter
      forloop.first
      forloop.last 
  • {% if ordered_warranty %}  {% else %} {% endif %}
  • 母板:{% block title %}{% endblock %}
    子板:{% extends “base.html” %}
       {% block title %}{% endblock %}
  • 援救方法:
    {{ item.event_start|date:”Y-m-d H:i:s”}}
    {{ bio|truncatewords:”30″ }}
    {{ my_list|first|upper }}
    {{ name|lower }}

 

b、Form上传文件实例

882828九五至尊手机版 54882828九五至尊手机版 55

# HTML

       <form method="post" action="/view1/" enctype="multipart/form-data">
           <input type="file" name="ExcelFile" id="id_ExcelFile" />
           <input type="submit" value="提交" />
       </form>



# Form

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

# Models

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

# Views

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

View Code

3、自定义simple_tag

a、在app中创建templatetags模块

b、创制任意 .py 文件,如:xx.py

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe
from django.template.base import resolve_variable, Node, TemplateSyntaxError

register = template.Library()

@register.simple_tag
def my_simple_time(v1,v2,v3):
    return  v1 + v2 + v3

@register.simple_tag
def my_input(id,arg):
    result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
    return mark_safe(result)

c、在应用自定义simple_tag的html文件中程导弹入在此之前创设的 xx.py 文件名

{% load xx %}

d、使用simple_tag

{% my_simple_time 1 2 3%}
{% my_input 'id_username' 'hide'%}

e、在settings中布置当前app,不然django不可能找到自定义的simple_tag

882828九五至尊手机版 56882828九五至尊手机版 57

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01',
)

View Code

 

 

c、ajax上传文件实例

882828九五至尊手机版 58882828九五至尊手机版 59

<div>
       {{ up.ExcelFile }}
       <input type="button" id="submitj" value="提交" />
   </div>


<script src="/static/js/jquery-2.1.4.min.js"></script>
<script>
    $('#submitj').bind("click",function () {
        var file = $('#id_ExcelFile')[0].files[0];
        var form = new FormData();
        form.append('ExcelFile', file);
         $.ajax({
                type:'POST',
                url: '/view1/',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
    })
</script>

HTML

882828九五至尊手机版 60882828九五至尊手机版 61

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

Form

882828九五至尊手机版 62882828九五至尊手机版 63

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

Models

882828九五至尊手机版 64882828九五至尊手机版 65

from study1 import forms

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

return render(request, 'file.html', locals())

View

 

六、Model 层

Django提供了一个抽象层(“Model”)的创设和保管Web应用程序的数目。

  • 各样模型是3个Python类,子类d jango.db.models.model
  • 模型中的各样属性代表一个数据库字段。

 

七、中间件(MiddleWare)

django 中的中间件(middleware),在django中,中间件其实便是叁个类,在呼吁到来和得了后,django会依据自个儿的条条框框在适合的火候执行中间件中相应的格局。

在django项目的settings模块中,有一个
MIDDLEWARE_CLASSES 变量,当中每二个要素正是2当中间件,如下图。

882828九五至尊手机版 66

与mange.py在同样目录下的公文夹
wupeiqi/middleware下的auth.py文件中的Authentication类

中间件中能够定义多个主意,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args,
    callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

剖析源码得知前叁个格局是在此此前以往进行的,后四个方法是从后往前进行的

882828九五至尊手机版 67

 所从前多个主意是呼吁进入时要穿越的,而后多少个章程是请求出去时要穿过的

一张图告诉您中间件的运维流程

882828九五至尊手机版 68

 

简言之的例证

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

 

自定义中间件

① 、创制中间件类

class Middle_Test(object):

    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        i =1
        pass
    def process_exception(self, request, exception):
        pass

    def process_response(self, request, response):
        return response

  

二 、注册中间件

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'sparks.middleware.auth.Middle_Test',
)

  

参数与字段

882828九五至尊手机版 69882828九五至尊手机版 70

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制
23、models.ImageField   图片
24、models.FilePathField 文件

越多字段

882828九五至尊手机版 71882828九五至尊手机版 72

1、null=True
  数据库中字段是否可以为空
2、blank=True
  django的 Admin 中添加数据时是否可允许空值
3、primary_key = False
  主键,对AutoField设置主键后,就会代替原来的自增 id 列
4、auto_now 和 auto_now_add
  auto_now   自动创建---无论添加或修改,都是当前操作的时间
  auto_now_add  自动创建---永远是创建时的时间
5、choices
GENDER_CHOICE = (
        (u'M', u'Male'),
        (u'F', u'Female'),
    )
gender = models.CharField(max_length=2,choices = GENDER_CHOICE)
6、max_length
7、default  默认值
8、verbose_name  Admin中字段的显示名称
9、name|db_column  数据库中的字段名称
10、unique=True  不允许重复
11、db_index = True  数据库索引
12、editable=True  在Admin里是否可编辑
13、error_messages=None  错误提示
14、auto_created=False  自动创建
15、help_text  在Admin中提示帮助信息
16、validators=[]
17、upload-to

越多参数

 

八、 Form

django中的Form一般有二种效能:

  • 输入html
  • 表达用户输入

882828九五至尊手机版 73882828九五至尊手机版 74

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'标题不能为空',
                                            'min_length': u'标题最少为5个字符',
                                            'max_length': u'标题最多为20个字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'标题5-20个字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手机不能为空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

Form

882828九五至尊手机版 75882828九五至尊手机版 76

def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))

示例

 

使用Form仍是能够自动生成前端的input标签:

882828九五至尊手机版 77882828九五至尊手机版 78

from app01 import models
from django import forms

class Form1(forms.Form):
    user = forms.CharField(
        widget=forms.TextInput(attrs={'class':'c1'}), # 给标签添加属性
        error_messages={'required':'用户名不能为空'}, # 自定义错误输出
    )
    pwd = forms.CharField(max_length=4, min_length=2)
    email = forms.EmailField(error_messages={'required':'邮箱不能为空', 'invalid':'邮箱格式错误'})

    memo = forms.CharField(
        widget=forms.Textarea()
    )
    # user_type_choice = (
    #     (0, '普通用户'),
    #     (1, '高级用户'),
    # )
    user_type_choice = models.BookType.objects.values_list("id", "caption")
    # 这样并不能跟数据库实时同步,因为静态字段不更新
    book_type = forms.CharField(
        widget=forms.widgets.Select(choices=user_type_choice)
    )
    def __init__(self, *args, **kwargs):
        super(Form1, self).__init__(*args, **kwargs)
        # 让选项框跟数据库进行实时联动,解决上一行注释的问题
        self.fields['book_type'] = forms.CharField(
            widget=forms.widgets.Select(choices=models.BookType.objects.values_list("id", "caption"))
        )

form.py

882828九五至尊手机版 79882828九五至尊手机版 80

def form1(request):

    if request.method == "POST":
        # 获取请求做验证
        f = Form1(request.POST)
        if f.is_valid():
            print(f.cleaned_data)
        else:
            pass
            # print(f.errors['user'][0])
            # print(f.errors['pwd'][0])
        return render(request, "form1.html", {'error': f.errors, 'form':f})
    else:
        f = Form1()
        return render(request, 'form1.html',{'form':f})

views.py

882828九五至尊手机版 81882828九五至尊手机版 82

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .input-group{
            position: relative;
            padding: 23px;

        }
        .input-group input{
            width: 200px;
            display: inline-block;
        }
        .input-group span{
            display: inline-block;
            position: absolute;
            height: 20px;
            background-color:coral;
            color: white;
            bottom: 1px;
            left: 22px;
            width: 204px;


        }
    </style>
</head>
<body>
    <div>
        <form action="/form/" method="post">
            <div class="input-group">
{#                <input type="text" name="user"/>#}
                {{ form.user }}
                {% if error.user.0 %}
                {{ error.user.0 }}
                {% endif %}
            </div>
            <div class="input-group">
{#                <input type="text" name="pwd"/>#}
                {{ form.pwd }}
                {% if error.pwd.0 %}
                {{ error.pwd.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.email }}
                {% if error.email.0 %}
                {{ error.email.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.memo }}
                {% if error.memo.0 %}
                {{ error.memo.0 }}
                {% endif %}
            </div>
            <div class="input-group">
                {{ form.book_type }}
                {% if error.book_type.0 %}
                {{ error.book_type.0 }}
                {% endif %}
            </div>
            <input type="submit" value="提交"/>
        </form>
    </div>

</body>
</html>

form1.html

 

扩展:ModelForm

在选取Model和Form时,都须要对字段实行定义并钦赐项目,通过ModelForm则足以省去From中字段的定义

882828九五至尊手机版 83882828九五至尊手机版 84

class AdminModelForm(forms.ModelForm):

    class Meta:
        model = models.Admin
        #fields = '__all__'
        fields = ('username', 'email')

        widgets = {
            'email' : forms.PasswordInput(attrs={'class':"alex"}),
        }

ModelForm

 

 

 

连表结构

  • 一对多:models.ForeignKey(其他表)
  • 多对多:models.ManyToManyField(其他表)
  • 一对一:models.OneToOneField(其他表)

 

⑨ 、 认证系统(auth)

auth模块是Django提供的科班权限管理体系,能够提供用户地点注解,
用户组管理,并且能够和admin模块同盟使用.

在INSTALLED_APPS中添加’django.contrib.auth’使用该APP, auth模块默许启用.

操作表

model

from django.contrib.auth.models import User

# 数据库中该表名为auth_user.
CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "password" varchar(128) NOT NULL, "last_login" datetime NULL, 
    "is_superuser" bool NOT NULL, 
    "first_name" varchar(30) NOT NULL, 
    "last_name" varchar(30) NOT NULL,
    "email" varchar(254) NOT NULL, 
    "is_staff" bool NOT NULL, 
    "is_active" bool NOT NULL,
    "date_joined" datetime NOT NULL,
    "username" varchar(30) NOT NULL UNIQUE
)

① 、基本操作

# 增    
models.Tb1.objects.create(c1='xx', c2='oo')  # 增加一条数据,可以接受字典类型数据 **kwargs

obj = models.Tb1(c1='xx', c2='oo')
obj.save()

# 查    
models.Tb1.objects.get(id=123)          # 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.all()                # 获取全部
models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

# 删    
models.Tb1.objects.filter(name='nick').delete() # 删除指定条件的数据

# 改models.Tb1.objects.filter(name='nick').update(gender='0')  # 将指定条件的数据更新,均支持 **kwargs
obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()                                                      # 修改单条数据

 

新建用户

user = User.objects.create_user(username, email, password)
user.save()

# 不存储用户密码明文而是存储一个Hash值

贰 、进阶操作(了不起的双下划线)

应用双下划线将字段和呼应的操作连接起来

# 获取个数
models.Tb1.objects.filter(name='nick').count()

# 大于,小于
models.Tb1.objects.filter(id__gt=1)              # 获取id大于1的值
models.Tb1.objects.filter(id__lt=10)             # 获取id小于10的值
models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值

# in
models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in

# contains
models.Tb1.objects.filter(name__contains="ven")
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
models.Tb1.objects.exclude(name__icontains="ven")

# range
models.Tb1.objects.filter(id__range=[1, 2])      # 范围bettwen and

# 其他类似
# startswith,istartswith, endswith, iendswith,

# order by
models.Tb1.objects.filter(name='nick').order_by('id')    # asc
models.Tb1.objects.filter(name='nick').order_by('-id')   # desc

# limit 、offset
models.Tb1.objects.all()[10:20]

# group by
from django.db.models import Count, Min, Max, Sum

models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
# SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

 

证实用户

882828九五至尊手机版 85

from django.contrib.auth import authenticate

user = authenticate(username=username, password=password)

# 认证用户的密码是否有效, 若有效则返回代表该用户的user对象, 若无效则返回None.
# 该方法不检查is_active标志位.

882828九五至尊手机版 86

③ 、连表操作(了不起的双下划线)

采用双下划线和 _set 将表之间的操作连接起来

882828九五至尊手机版 87882828九五至尊手机版 88

class UserProfile(models.Model):
    user_info = models.OneToOneField('UserInfo')
    username = models.CharField(max_length=64)
    password = models.CharField(max_length=64)

    def __unicode__(self):
        return self.username


class UserInfo(models.Model):
    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )
    user_type = models.IntegerField(choices=user_type_choice)
    name = models.CharField(max_length=32)
    email = models.CharField(max_length=32)
    address = models.CharField(max_length=128)

    def __unicode__(self):
        return self.name


class UserGroup(models.Model):

    caption = models.CharField(max_length=64)

    user_info = models.ManyToManyField('UserInfo')

    def __unicode__(self):
        return self.caption


class Host(models.Model):
    hostname = models.CharField(max_length=64)
    ip = models.GenericIPAddressField()
    user_group = models.ForeignKey('UserGroup')

    def __unicode__(self):
        return self.hostname

表结构实例

882828九五至尊手机版 89882828九五至尊手机版 90

user_info_obj = models.UserInfo.objects.filter(id=1).first()
print user_info_obj.user_type
print user_info_obj.get_user_type_display()
print user_info_obj.userprofile.password

user_info_obj = models.UserInfo.objects.filter(id=1).values('email', 'userprofile__username').first()
print user_info_obj.keys()
print user_info_obj.values()

极度操作

882828九五至尊手机版 91882828九五至尊手机版 92

    # 添加一对多
    dic = {
        "hostname": "名字1",
        "ip": "192.168.1.1",
        "user_group_id": 1,   # 加对象则为"user_group"
    }
    models.Host.objects.create(**dic)

    # 正向查一对多
    host_obj = models.Host.objects.all()
    print(type(host_obj),     # <class 'django.db.models.query.QuerySet'>
          host_obj)           # <QuerySet [<Host: 名字1>]>
    for item in host_obj:
        print(item.hostname)
        print(item.user_group.caption)
        print(item.user_group.user_info.values())
        # <QuerySet [{'name': 'nick', 'user_type': 1, 'id': 1, 'email': '630571017@qq.com', 'address': '128号'}]>

    usergroup_obj = models.Host.objects.filter(user_group__caption='标题1')
    print(usergroup_obj)


    # 反向查一对多
    usergroup_obj = models.UserGroup.objects.get(id=1)
    print(usergroup_obj.caption)
    ret = usergroup_obj.host_set.all()  # 所有关于id=1的host
    print(ret)

    obj = models.UserGroup.objects.filter(host__ip='192.168.1.1').\
        values('host__id', 'host__hostname')
    print(obj)      # <QuerySet [{'host__id': 1, 'host__hostname': '名字1'}]>

一对多

882828九五至尊手机版 93882828九五至尊手机版 94

user_info_obj = models.UserInfo.objects.get(name='nick')
user_info_objs = models.UserInfo.objects.all()

group_obj = models.UserGroup.objects.get(caption='CTO')
group_objs = models.UserGroup.objects.all()

# 添加数据
#group_obj.user_info.add(user_info_obj)
#group_obj.user_info.add(*user_info_objs)

# 删除数据
#group_obj.user_info.remove(user_info_obj)
#group_obj.user_info.remove(*user_info_objs)

# 添加数据
#user_info_obj.usergroup_set.add(group_obj)
#user_info_obj.usergroup_set.add(*group_objs)

# 删除数据
#user_info_obj.usergroup_set.remove(group_obj)
#user_info_obj.usergroup_set.remove(*group_objs)

# 获取数据
#print group_obj.user_info.all()
#print group_obj.user_info.all().filter(id=1)

# 获取数据
#print user_info_obj.usergroup_set.all()
#print user_info_obj.usergroup_set.all().filter(caption='CTO')
#print user_info_obj.usergroup_set.all().filter(caption='DBA')

    # 添加多对多
    # userinfo_id_1 = models.UserInfo.objects.filter(id=1)
    # usergroup_id_1 = models.UserGroup.objects.filter(id=1).first()
    # usergroup_id_1.user_info.add(*userinfo_id_1)

多对多操作

882828九五至尊手机版 95882828九五至尊手机版 96

    # F 使用查询条件的值(用原来的值操作)
    #
    # from django.db.models import F
    # models.Tb1.objects.update(num=F('num')+1)


    # Q 构建搜索条件
    from django.db.models import Q
    # con = Q()
    #
    # q1 = Q()
    # q1.connector = 'OR'
    # q1.children.append(('id', 1))
    # q1.children.append(('id', 10))
    # q1.children.append(('id', 9))
    #
    # q2 = Q()
    # q2.connector = 'OR'
    # q2.children.append(('c1', 1))
    # q2.children.append(('c1', 10))
    # q2.children.append(('c1', 9))
    #
    # con.add(q1, 'AND')
    # con.add(q2, 'AND')
    #
    # models.Tb1.objects.filter(con)

F & Q

882828九五至尊手机版 97882828九五至尊手机版 98

    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("""SELECT * from app1_userinfo where name = %s""", ['nick'])
    row = cursor.fetchone()
    print(row)

Django 执行原生SQL

注意:xx_set中的【_set】是多对多中的固定搭配

修改密码

882828九五至尊手机版 99

user.set_password(new_password)

# 以下实例为先认证通过后才可以修改密码
user = auth.authenticate(username=username, password=old_password)
if user is not None:
    user.set_password(new_password)
    user.save()

882828九五至尊手机版 100

 

登录

882828九五至尊手机版 101

from django.contrib.auth import login

# login向session中添加SESSION_KEY, 便于对用户进行跟踪:
'login(request, user)'

# login不进行认证,也不检查is_active标志位
# 实例
user = authenticate(username=username, password=password)
if user is not None:
    if user.is_active:
        login(request, user)

882828九五至尊手机版 102

扩展:

脱离登录

882828九五至尊手机版 103

# logout会移除request中的user信息, 并刷新session

from django.contrib.auth import logout

def logout_view(request):
    logout(request)

882828九五至尊手机版 104

a、自定义上传

882828九五至尊手机版 105882828九五至尊手机版 106

def upload_file(request):
    if request.method == "POST":
        obj = request.FILES.get('fafafa')
        f = open(obj.name, 'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
    return render(request, 'file.html')

View Code

只同意登录的用户访问

@login_required修饰器修饰的view函数会先通过session key检查是或不是登录,
已登录用户能够不奇怪的实践操作,
未登录用户将被重定向到login_url钦赐的地方.

若未钦命login_url参数, 则重定向到settings.LOGIN_URL

882828九五至尊手机版 107

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def userinfo(request):
    ...

# settings 配置
LOGIN_URL = '/index/'
# views
@login_required
def userinfo(request):
    ...

882828九五至尊手机版 108

 

 

b、Form上传文件实例

882828九五至尊手机版 109882828九五至尊手机版 110

       <form method="post" action="/view1/" enctype="multipart/form-data">
           <input type="file" name="ExcelFile" id="id_ExcelFile" />
           <input type="submit" value="提交" />
       </form>

HTML

882828九五至尊手机版 111882828九五至尊手机版 112

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

Form

882828九五至尊手机版 113882828九五至尊手机版 114

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

models

882828九五至尊手机版 115882828九五至尊手机版 116

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

View

10、 跨站请求伪造(csrf)

django为用户完结幸免跨站请求伪造的效果,通过中间件 django.middleware.csrf.CsrfViewMiddleware
来达成。而对于django中设置防跨站请求伪造效率有分为全局和有些。

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,为当前函数强制安装防跨站请求伪造效率,固然settings中尚无设置全局中间件。
  • @csrf_exempt,打消当前函数防跨站请求伪造效率,尽管settings中装置了大局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

  在Django1.第10中学,为了防止BREACH攻击,对cookie-form类型的csrf做了几许更上一层楼,即在cookie和form中的token值是分裂的

 

c、ajax上传文件实例

882828九五至尊手机版 117882828九五至尊手机版 118

   <div>
       {{ up.ExcelFile }}
       <input type="button" id="submitj" value="提交" />
   </div>


<script src="/static/js/jquery-2.1.4.min.js"></script>
<script>
    $('#submitj').bind("click",function () {
        var file = $('#id_ExcelFile')[0].files[0];
        var form = new FormData();
        form.append('ExcelFile', file);
         $.ajax({
                type:'POST',
                url: '/view1/',
                data: form,
                processData: false,  // tell jQuery not to process the data
                contentType: false,  // tell jQuery not to set contentType
                success: function(arg){
                    console.log(arg);
                }
            })
    })
</script>

HTML

882828九五至尊手机版 119882828九五至尊手机版 120

class FileForm(forms.Form):
    ExcelFile = forms.FileField()

Form

882828九五至尊手机版 121882828九五至尊手机版 122

from django.db import models

class UploadFile(models.Model):
    userid = models.CharField(max_length = 30)
    file = models.FileField(upload_to = './upload/')
    date = models.DateTimeField(auto_now_add=True)

models

882828九五至尊手机版 123882828九五至尊手机版 124

from study1 import forms

def UploadFile(request):
    uf = AssetForm.FileForm(request.POST,request.FILES)
    if uf.is_valid():
            upload = models.UploadFile()
            upload.userid = 1
            upload.file = uf.cleaned_data['ExcelFile']
            upload.save()

            print upload.file

return render(request, 'file.html', locals())

View

 

 

应用

七、Form

django中的Form一般有二种作用:

  • 输入html
  • 证实用户输入

882828九五至尊手机版 125882828九五至尊手机版 126

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import re
from django import forms
from django.core.exceptions import ValidationError


def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')


class PublishForm(forms.Form):

    user_type_choice = (
        (0, u'普通用户'),
        (1, u'高级用户'),
    )

    user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice,
                                                                  attrs={'class': "form-control"}))

    title = forms.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': u'标题不能为空',
                                            'min_length': u'标题最少为5个字符',
                                            'max_length': u'标题最多为20个字符'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'标题5-20个字符'}))

    memo = forms.CharField(required=False,
                           max_length=256,
                           widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'详细描述', 'rows': 3}))

    phone = forms.CharField(validators=[mobile_validate, ],
                            error_messages={'required': u'手机不能为空'},
                            widget=forms.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))

    email = forms.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

Form

882828九五至尊手机版 127882828九五至尊手机版 128

def publish(request):
    ret = {'status': False, 'data': '', 'error': '', 'summary': ''}
    if request.method == 'POST':
        request_form = PublishForm(request.POST)
        if request_form.is_valid():
            request_dict = request_form.clean()
            print request_dict
            ret['status'] = True
        else:
            error_msg = request_form.errors.as_json()
            ret['error'] = json.loads(error_msg)
    return HttpResponse(json.dumps(ret))

View Code

扩展:ModelForm

在利用Model和Form时,都急需对字段举行定义并钦点项目,通过ModelForm则足以省去From中字段的定义

882828九五至尊手机版 129882828九五至尊手机版 130

class AdminModelForm(forms.ModelForm):

    class Meta:
        model = models.Admin
        #fields = '__all__'
        fields = ('username', 'email')

        widgets = {
            'email' : forms.PasswordInput(attrs={'class':"alex"}),
        }

View Code

 

 

壹 、普通表单

veiw中设置返回值:
     return render(request, 'xxx.html', data)

html中设置Token:
  {% csrf_token %}

  

捌 、认证系统auth 

auth模块是Django提供的规范权限管理连串,能够提供用户身份验证,
用户组管理,并且能够和admin模块同盟使用.

在INSTALLED_APPS中添加’django.contrib.auth’使用该APP, auth模块暗许启用.

2、Ajax

对于价值观的form,能够透过表单的法子将token再一次发送到服务端,而对此ajax的话,使用如下形式。

882828九五至尊手机版 131882828九五至尊手机版 132

# view.py

from django.template.context import RequestContext
# Create your views here.


def test(request):

    if request.method == 'POST':
        print request.POST
        return HttpResponse('ok')
    return  render_to_response('app01/test.html',context_instance=RequestContext(request))

view.py

882828九五至尊手机版 133882828九五至尊手机版 134

# text.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {% csrf_token %}

    <input type="button" onclick="Do();"  value="Do it"/>

    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
        var csrftoken = $.cookie('csrftoken');

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
        function Do(){

            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });

        }
    </script>
</body>
</html>

text.html

更多:https://docs.djangoproject.com/en/dev/ref/csrf/#ajax

 

model

from django.contrib.auth.models import User

# 数据库中该表名为auth_user.
CREATE TABLE "auth_user" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, 
    "password" varchar(128) NOT NULL, "last_login" datetime NULL, 
    "is_superuser" bool NOT NULL, 
    "first_name" varchar(30) NOT NULL, 
    "last_name" varchar(30) NOT NULL,
    "email" varchar(254) NOT NULL, 
    "is_staff" bool NOT NULL, 
    "is_active" bool NOT NULL,
    "date_joined" datetime NOT NULL,
    "username" varchar(30) NOT NULL UNIQUE
)

十一、 分页

新建用户

user = User.objects.create_user(username, email, password)
user.save()

# 不存储用户密码明文而是存储一个Hash值

1. Django内置分页

882828九五至尊手机版 135882828九五至尊手机版 136

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

L = []
for i in range(999):
    L.append(i)

def index(request):
    current_page = request.GET.get('p')

    paginator = Paginator(L, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
    return render(request, 'index.html', {'posts': posts})

views.py

882828九五至尊手机版 137882828九五至尊手机版 138

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<ul>
    {% for item in posts %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">

        {% if posts.has_previous %}
            <a href="?p={{ posts.previous_page_number }}">Previous</a>
        {% endif %}

            Page {{ posts.number }} of {{ posts.paginator.num_pages }}.

          {% if posts.has_next %}
              <a href="?p={{ posts.next_page_number }}">Next</a>
          {% endif %}


</div>
</body>
</html>

Html

882828九五至尊手机版 139882828九五至尊手机版 140

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger


class CustomPaginator(Paginator):
    def __init__(self, current_page, max_pager_num, *args, **kwargs):
        """
        :param current_page: 当前页
        :param max_pager_num:最多显示的页码个数
        :param args:
        :param kwargs:
        :return:
        """
        self.current_page = int(current_page)
        self.max_pager_num = max_pager_num
        super(CustomPaginator, self).__init__(*args, **kwargs)

    def page_num_range(self):
        # 当前页面
        # self.current_page
        # 总页数
        # self.num_pages
        # 最多显示的页码个数
        # self.max_pager_num
        print(1)
        if self.num_pages < self.max_pager_num:
            return range(1, self.num_pages + 1)
        print(2)
        part = int(self.max_pager_num / 2)
        if self.current_page - part < 1:
            return range(1, self.max_pager_num + 1)
        print(3)
        if self.current_page + part > self.num_pages:
            return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1)
        print(4)
        return range(self.current_page - part, self.current_page + part + 1)


L = []
for i in range(999):
    L.append(i)

def index(request):
    current_page = request.GET.get('p')
    paginator = CustomPaginator(current_page, 11, L, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象
    try:
        posts = paginator.page(current_page)
        # has_next              是否有下一页
        # next_page_number      下一页页码
        # has_previous          是否有上一页
        # previous_page_number  上一页页码
        # object_list           分页之后的数据列表
        # number                当前页
        # paginator             paginator对象
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)

    return render(request, 'index.html', {'posts': posts})

扩充内置分页:views.py

882828九五至尊手机版 141882828九五至尊手机版 142

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<ul>
    {% for item in posts %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">

{% if posts.has_previous %}
    <a href="?p={{ posts.previous_page_number }}">Previous</a>
{% endif %}

    {% for i in posts.paginator.page_num_range %}
        <a href="?p={{ i }}">{{ i }}</a>
    {% endfor %}

    {% if posts.has_next %}
        <a href="?p={{ posts.next_page_number }}">Next</a>
    {% endif %}



Page {{ posts.number }} of {{ posts.paginator.num_pages }}.


</div>
</body>
</html>

恢宏内置分页:Html

申明用户

from django.contrib.auth import authenticate

user = authenticate(username=username, password=password)

# 认证用户的密码是否有效, 若有效则返回代表该用户的user对象, 若无效则返回None.
# 该方法不检查is_active标志位.

2. 自定义分页

分页效用在各样网站都是不可或缺的,对于分页来说,其实就是基于用户的输入总括出应该在数据库表中的苗子地点。

壹 、设定每页突显数据条数

② 、用户输入页码(第三页、第②页…)

三 、依照设定的每页突显条数和脚下页码,总计出须要取数据表的开头地方

④ 、在数据表中依照初步地方取值,页面上输出数据


须求又来了,须要在页面上海展览中心示分页的页面。如:[上一页][1][2][3][4][5][下一页]

① 、设定每页突显数据条数

贰 、用户输入页码(第二页、第壹页…)

三 、设定突显多少页号

肆 、获取当前数码总条数

五 、遵照设定展现多少页号和数目总条数计算出,总页数

六 、依据设定的每页突显条数和脚下页码,计算出需求取数据表的序幕地点

⑦ 、在数据表中根据发轫地方取值,页面上输出数据

8、输出分页html,如:[上一页][1][2][3][4][5][下一页]

882828九五至尊手机版 143882828九五至尊手机版 144

#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe

class PageInfo(object):
    def __init__(self,current,totalItem,peritems=5):
        self.__current=current
        self.__peritems=peritems
        self.__totalItem=totalItem
    def From(self):
        return (self.__current-1)*self.__peritems
    def To(self):
        return self.__current*self.__peritems
    def TotalPage(self):  #总页数
        result=divmod(self.__totalItem,self.__peritems)
        if result[1]==0:
            return result[0]
        else:
            return result[0]+1

def Custompager(baseurl,currentPage,totalpage):  #基础页,当前页,总页数
    perPager=11
    #总页数<11
    #0 -- totalpage
    #总页数>11
        #当前页大于5 currentPage-5 -- currentPage+5
            #currentPage+5是否超过总页数,超过总页数,end就是总页数
        #当前页小于5 0 -- 11
    begin=0
    end=0
    if totalpage <= 11:
        begin=0
        end=totalpage
    else:
        if currentPage>5:
            begin=currentPage-5
            end=currentPage+5
            if end > totalpage:
                end=totalpage
        else:
            begin=0
            end=11
    pager_list=[]
    if currentPage<=1:
        first="<a href=''>首页</a>"
    else:
        first="<a href='%s%d'>首页</a>" % (baseurl,1)
    pager_list.append(first)

    if currentPage<=1:
        prev="<a href=''>上一页</a>"
    else:
        prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
    pager_list.append(prev)

    for i in range(begin+1,end+1):
        if i == currentPage:
            temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
        else:
            temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
        pager_list.append(temp)
    if currentPage>=totalpage:
        next="<a href='#'>下一页</a>"
    else:
        next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
    pager_list.append(next)
    if currentPage>=totalpage:
        last="<a href=''>末页</a>"
    else:
        last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
    pager_list.append(last)
    result=''.join(pager_list)
    return mark_safe(result)   #把字符串转成html语言

分页实例

总计,分页时索要做三件事:

  • 始建处理分页数据的类
  • 依照分页数据获取数据
  • 出口分页HTML,即:[上一页][1][2][3][4][5][下一页]

 

修改密码

user.set_password(new_password)

# 以下实例为先认证通过后才可以修改密码
user = auth.authenticate(username=username, password=old_password)
if user is not None:
    user.set_password(new_password)
    user.save()

十二、 Cookie

登录

from django.contrib.auth import login

# login向session中添加SESSION_KEY, 便于对用户进行跟踪:
'login(request, user)'

# login不进行认证,也不检查is_active标志位
# 实例
user = authenticate(username=username, password=password)
if user is not None:
    if user.is_active:
        login(request, user)

1. 获取Cookie:

1
2
3
4
5
6
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间

退出登录

# logout会移除request中的user信息, 并刷新session

from django.contrib.auth import logout

def logout_view(request):
    logout(request)

2. 设置Cookie:

1
2
3
4
5
6
7
8
9
10
11
12
13
rep = HttpResponse(...) 或 rep = render(request, ...)
 
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
    参数:
        key,              键
        value='',         值
        max_age=None,     超时时间
        expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

出于cookie保存在客户端的微型计算机上,所以,JavaScript和jquery也得以操作cookie。

1
2
<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num"30,{ path: '/' });

只同意登录的用户访问

@login_required修饰器修饰的view函数会先经过session key检查是或不是登录,
已报到用户能够平常的施行操作,
未登录用户将被重定向到login_url点名的地点.

若未内定login_url参数, 则重定向到settings.LOGIN_URL

from django.contrib.auth.decorators import login_required

@login_required(login_url='/accounts/login/')
def userinfo(request):
    ...

# settings 配置
LOGIN_URL = '/index/'
# views
@login_required
def userinfo(request):
    ...

 

 

玖 、跨站请求伪造

十三、 Session

Django中默许协助Session,其里面提供了5种档次的Session供开发者使用:

  • 数据库(默认)
  • 缓存
  • 文件
  • 缓存+数据库
  • 加密cookie

简介

django为用户完结制止跨站请求伪造的效果,通过中间件 django.middleware.csrf.CsrfViewMiddleware
来成功。而对于django中设置防跨站请求伪造功用有分为全局和部分。

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

  • @csrf_protect,为当前函数强制安装防跨站请求伪造效用,固然settings中从未安装全局中间件。
  • @csrf_exempt,废除当前函数防跨站请求伪造成效,就算settings中设置了全局中间件。

注:from django.views.decorators.csrf import csrf_exempt,csrf_protect

 

1、数据库Session

882828九五至尊手机版 145882828九五至尊手机版 146

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)



b. 使用

    def index(request):
        # 获取、设置、删除Session中数据
        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在则不设置
        del request.session['k1']

        # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()


        # 用户session的随机字符串
        request.session.session_key

        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()

        # 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")

        # 删除当前用户的所有Session数据
        request.session.delete("session_key")

        ...

View Code

应用

2、缓存Session

882828九五至尊手机版 147882828九五至尊手机版 148

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置


    SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存



b. 使用

    同上

View Code

壹 、普通表单

veiw中设置返回值:
  return render_to_response('Account/Login.html',data,context_instance=RequestContext(request))  
     或者
     return render(request, 'xxx.html', data)

html中设置Token:
  {% csrf_token %}

3、文件Session

882828九五至尊手机版 149882828九五至尊手机版 150

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T


    SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存

b. 使用

    同上

View Code

2、Ajax

对此守旧的form,能够透过表单的主意将token再一次发送到服务端,而对此ajax的话,使用如下格局。

882828九五至尊手机版 151882828九五至尊手机版 152

# view.py

from django.template.context import RequestContext
# Create your views here.


def test(request):

    if request.method == 'POST':
        print request.POST
        return HttpResponse('ok')
    return  render_to_response('app01/test.html',context_instance=RequestContext(request))

view.py

882828九五至尊手机版 153882828九五至尊手机版 154

# text.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    {% csrf_token %}

    <input type="button" onclick="Do();"  value="Do it"/>

    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
        var csrftoken = $.cookie('csrftoken');

        function csrfSafeMethod(method) {
            // these HTTP methods do not require CSRF protection
            return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
        }
        $.ajaxSetup({
            beforeSend: function(xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                    xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
            }
        });
        function Do(){

            $.ajax({
                url:"/app01/test/",
                data:{id:1},
                type:'POST',
                success:function(data){
                    console.log(data);
                }
            });

        }
    </script>
</body>
</html>

text.html

更多:https://docs.djangoproject.com/en/dev/ref/csrf/\#ajax

 

 

4、缓存+数据库Session

882828九五至尊手机版 155882828九五至尊手机版 156

数据库用于做持久化,缓存用于提高效率

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

b. 使用

    同上

View Code

十、分页

5、加密cookie Session

882828九五至尊手机版 157882828九五至尊手机版 158

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

b. 使用

    同上

View Code

跟数据库的操作一样,在Django中差别缓存方式的利用办法是平等的,想要改变缓存的花色只必要转移上述相应铺排即可。

越来越多参考:碰上那里 和 冲击那里

扩展:Session用户验证(装饰器)

def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陆,跳转到指定页面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap

  

Django内置分页 

Paginator

 

十四、 缓存

出于Django是动态网站,全部每一趟请求均会去数据实行相应的操作,当程序访问量大时,耗时自然会越加显然,最简便易行解决措施是运用:缓存,缓存将二个某部views的重临值保存至内部存款和储蓄器依旧memcache中,五分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内部存储器依旧Redis中以前缓存的剧情得到,并赶回。

Django中提供了6种缓存形式:

  • 付出调节和测试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

和数据库类似,缓存的具体操作都以一致的,使用区其他不二法门只须要将配备改掉即可

1、配置

a、开发调节和测试

882828九五至尊手机版 159882828九五至尊手机版 160

# 此为开始调试用,实际内部不做任何操作
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
                'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
                'OPTIONS':{
                    'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
                    'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                },
                'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
                'VERSION': 1,                                                 # 缓存key的版本(默认1)
                'KEY_FUNCTION' 函数名                                          # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
            }
        }


    # 自定义key
    def default_key_func(key, key_prefix, version):
        """
        Default function to generate keys.

        Constructs the key used by all other methods. By default it prepends
        the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
        function with custom key making behavior.
        """
        return '%s:%s:%s' % (key_prefix, version, key)

    def get_key_func(key_func):
        """
        Function to decide which key function to use.

        Defaults to ``default_key_func``.
        """
        if key_func is not None:
            if callable(key_func):
                return key_func
            else:
                return import_string(key_func)
        return default_key_func

View Code

b、内存

882828九五至尊手机版 161882828九五至尊手机版 162

# 此缓存将内容保存至内存的变量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其他配置同开发调试版本

View Code

c、文件

882828九五至尊手机版 163882828九五至尊手机版 164

# 此缓存将内容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其他配置同开发调试版本

View Code

d、数据库

882828九五至尊手机版 165882828九五至尊手机版 166

# 此缓存将内容保存至数据库

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 数据库表
            }
        }

    # 注:执行创建表命令 python manage.py createcachetable

View Code

e、Memcache缓存(python-memcached模块)

882828九五至尊手机版 167882828九五至尊手机版 168

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

f、Memcache缓存(pylibmc模块)

882828九五至尊手机版 169882828九五至尊手机版 170

# 此缓存使用pylibmc模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

 

2、应用

a. 全站使用

882828九五至尊手机版 171882828九五至尊手机版 172

使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

    MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中间件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""

View Code

b. 单独视图缓存

882828九五至尊手机版 173882828九五至尊手机版 174

方式一:
        from django.views.decorators.cache import cache_page

        @cache_page(60 * 15)
        def my_view(request):
            ...

    方式二:
        from django.views.decorators.cache import cache_page

        urlpatterns = [
            url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
        ]

View Code

c、局地视图使用

882828九五至尊手机版 175882828九五至尊手机版 176

a. 引入TemplateTag

        {% load cache %}

    b. 使用缓存

        {% cache 5000 缓存key %}
            缓存内容
        {% endcache %}

View Code

注:如若出现多少个url匹配同一个view函数的情事,缓存机制会遵照每3个两样的url做单独的缓存

更多:冲击那里

 

 

自定义分页

882828九五至尊手机版 177882828九五至尊手机版 178

#!/usr/bin/env python
# _*_coding:utf-8_*_
from django.utils.safestring import mark_safe

class PageInfo(object):
    def __init__(self,current,totalItem,peritems=5):
        self.__current=current
        self.__peritems=peritems
        self.__totalItem=totalItem
    def From(self):
        return (self.__current-1)*self.__peritems
    def To(self):
        return self.__current*self.__peritems
    def TotalPage(self):  #总页数
        result=divmod(self.__totalItem,self.__peritems)
        if result[1]==0:
            return result[0]
        else:
            return result[0]+1

def Custompager(baseurl,currentPage,totalpage):  #基础页,当前页,总页数
    perPager=11
    #总页数<11
    #0 -- totalpage
    #总页数>11
        #当前页大于5 currentPage-5 -- currentPage+5
            #currentPage+5是否超过总页数,超过总页数,end就是总页数
        #当前页小于5 0 -- 11
    begin=0
    end=0
    if totalpage <= 11:
        begin=0
        end=totalpage
    else:
        if currentPage>5:
            begin=currentPage-5
            end=currentPage+5
            if end > totalpage:
                end=totalpage
        else:
            begin=0
            end=11
    pager_list=[]
    if currentPage<=1:
        first="<a href=''>首页</a>"
    else:
        first="<a href='%s%d'>首页</a>" % (baseurl,1)
    pager_list.append(first)

    if currentPage<=1:
        prev="<a href=''>上一页</a>"
    else:
        prev="<a href='%s%d'>上一页</a>" % (baseurl,currentPage-1)
    pager_list.append(prev)

    for i in range(begin+1,end+1):
        if i == currentPage:
            temp="<a href='%s%d' class='selected'>%d</a>" % (baseurl,i,i)
        else:
            temp="<a href='%s%d'>%d</a>" % (baseurl,i,i)
        pager_list.append(temp)
    if currentPage>=totalpage:
        next="<a href='#'>下一页</a>"
    else:
        next="<a href='%s%d'>下一页</a>" % (baseurl,currentPage+1)
    pager_list.append(next)
    if currentPage>=totalpage:
        last="<a href=''>末页</a>"
    else:
        last="<a href='%s%d'>末页</a>" % (baseurl,totalpage)
    pager_list.append(last)
    result=''.join(pager_list)
    return mark_safe(result)   #把字符串转成html语言

分页实例

 

 

十五、 序列化

有关Django中的体系化首要利用在将数据库中寻找的多少再次回到给客户端用户,特其他Ajax请求一般重临的为Json格式。

十一、Cookice

1. serializers

1
2
3
4
5
from django.core import serializers
 
ret = models.BookType.objects.all()
 
data = serializers.serialize("json", ret)

获取Cookie:

request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
    参数:
        default: 默认值
           salt: 加密盐
        max_age: 后台控制过期时间

 

2. json.dumps

1
2
3
4
5
6
7
8
import json
 
#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')
 
ret=list(ret)
 
result = json.dumps(ret)

由于json.dumps时心慌意乱处理datetime日期,所以能够透过自定义处理器来做扩展,如:

882828九五至尊手机版 179882828九五至尊手机版 180

import json 
from datetime import date 
from datetime import datetime 

class JsonCustomEncoder(json.JSONEncoder): 

    def default(self, field): 

        if isinstance(field, datetime): 
            return o.strftime('%Y-%m-%d %H:%M:%S') 
        elif isinstance(field, date): 
            return o.strftime('%Y-%m-%d') 
        else: 
            return json.JSONEncoder.default(self, field) 


# ds = json.dumps(d, cls=JsonCustomEncoder) 

自定义示例

 

设置Cookie:

rep = HttpResponse(...) 或 rep = render(request, ...)

rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
    参数:
        key,              键
        value='',         值
        max_age=None,     超时时间
        expires=None,     超时时间(IE requires expires, so set it if hasn't been already.)
        path='/',         Cookie生效的路径,/ 表示根路径,特殊的:跟路径的cookie可以被任何url的页面访问
        domain=None,      Cookie生效的域名
        secure=False,     https传输
        httponly=False    只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

出于cookie保存在客户端的电脑上,所以,JavaScript和jquery也得以操作cookie。

<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });

 

 

十六、 信号

Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,便是有的动作产生的时候,信号允许特定的发送者去提示部分接受者。

一 、Django内置信号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Model signals
    pre_init                    # django的modal执行其构造方法前,自动触发
    post_init                   # django的modal执行其构造方法后,自动触发
    pre_save                    # django的modal对象保存前,自动触发
    post_save                   # django的modal对象保存后,自动触发
    pre_delete                  # django的modal对象删除前,自动触发
    post_delete                 # django的modal对象删除后,自动触发
    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
    pre_migrate                 # 执行migrate命令前,自动触发
    post_migrate                # 执行migrate命令后,自动触发
Request/response signals
    request_started             # 请求到来前,自动触发
    request_finished            # 请求结束后,自动触发
    got_request_exception       # 请求异常后,自动触发
Test signals
    setting_changed             # 使用test测试修改配置文件时,自动触发
    template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
    connection_created          # 创建数据库连接时,自动触发

对于Django内置的信号,仅需注册钦命信号,当程序执行相应操作时,自动触发注册函数:

882828九五至尊手机版 181882828九五至尊手机版 182

    from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception

    from django.db.models.signals import class_prepared
    from django.db.models.signals import pre_init, post_init
    from django.db.models.signals import pre_save, post_save
    from django.db.models.signals import pre_delete, post_delete
    from django.db.models.signals import m2m_changed
    from django.db.models.signals import pre_migrate, post_migrate

    from django.test.signals import setting_changed
    from django.test.signals import template_rendered

    from django.db.backends.signals import connection_created


    def callback(sender, **kwargs):
        print("xxoo_callback")
        print(sender,kwargs)

    xxoo.connect(callback)
    # xxoo指上述导入的内容

View Code

 

十二、Session

Django中暗中同意支持Session,其里面提供了5连串型的Session供开发者使用:

  • 数据库(默认)
  • 缓存
  • 文件
  • 缓存+数据库
  • 加密cookie

贰 、自定义信号

a. 定义并登记信号

# 自定制信号
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

def callback(sender, **kwargs):
    print("self-define")
    print(sender, kwargs)

pizza_done.connect(callback)

  

b. 触发信号

from 路径 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

  

是因为放置信号的触发者已经济合营并到Django中,所以其会自动调用,而对此自定义信号则要求开发者在肆意地点触发。

更多:撞倒那里

 

1、数据库Session

882828九五至尊手机版 183882828九五至尊手机版 184

Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)

    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)



b. 使用

    def index(request):
        # 获取、设置、删除Session中数据
        request.session['k1']
        request.session.get('k1',None)
        request.session['k1'] = 123
        request.session.setdefault('k1',123) # 存在则不设置
        del request.session['k1']

        # 所有 键、值、键值对
        request.session.keys()
        request.session.values()
        request.session.items()
        request.session.iterkeys()
        request.session.itervalues()
        request.session.iteritems()


        # 用户session的随机字符串
        request.session.session_key

        # 将所有Session失效日期小于当前日期的数据删除
        request.session.clear_expired()

        # 检查 用户session的随机字符串 在数据库中是否
        request.session.exists("session_key")

        # 删除当前用户的所有Session数据
        request.session.delete("session_key")

        ...

View Code

十七、admin

django
amdin是django提供的三个后台管理页面,改管理页面提供完善的html和css,使得你在经过Model创设完数据库表之后,就能够对数码进行增加和删除改查,而接纳django
admin 则供给以下步骤:

  • 开创后台管理员
  • 配置url
  • 登记和配备django admin后台管理页面

注:不建议新手平日选拔admin,会形成重视,大旨的是model模块的操作!

2、缓存Session

882828九五至尊手机版 185882828九五至尊手机版 186

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置


    SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存



b. 使用

    同上

View Code

① 、创制后台管理员

python manage.py createsuperuser

3、文件Session

882828九五至尊手机版 187882828九五至尊手机版 188

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T


    SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
    SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
    SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
    SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
    SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
    SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
    SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存

b. 使用

    同上

View Code

② 、配置后台管理url(暗许已配)

url(r'^admin/', include(admin.site.urls))

4、缓存+数据库Session

882828九五至尊手机版 189882828九五至尊手机版 190

数据库用于做持久化,缓存用于提高效率

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎

b. 使用

    同上

View Code

三 、注册和配置django admin 后台管理页面

5、加密cookie Session

882828九五至尊手机版 191882828九五至尊手机版 192

a. 配置 settings.py

    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎

b. 使用

    同上

View Code

更加多参考:冲击那里 和 相撞那里

壮大:Session用户验证

def login(func):
    def wrap(request, *args, **kwargs):
        # 如果未登陆,跳转到指定页面
        if request.path == '/test/':
            return redirect('http://www.baidu.com')
        return func(request, *args, **kwargs)
    return wrap

 

a、在admin中执行如下配置

882828九五至尊手机版 193882828九五至尊手机版 194

from django.contrib import admin

from app01 import  models

admin.site.register(models.UserType)
admin.site.register(models.UserInfo)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

6、Redis 实现 

b、设置数据表名称

882828九五至尊手机版 195882828九五至尊手机版 196

class UserType(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = '用户类型'
        verbose_name_plural = '用户类型'

View Code

环境设置

pip install django-redis
pip install django-redis-cache
pip install django-redis-sessions
c、打开表之后,设定默许显示,供给在model中作如下配置

882828九五至尊手机版 197882828九五至尊手机版 198

class UserType(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):  # python3 is __str__(self)
        return self.name

View Code

1> 配置django-redis-sessions

在settings.py中配置

SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'
# SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = 'password'
SESSION_REDIS_PREFIX = 'session'
SESSION_COOKIE_NAME = 'session_name'
SESSION_COOKIE_AGE = '60*20'  # 超时时间


# If you prefer domain socket connection, you can just add this line instead of SESSION_REDIS_HOST and SESSION_REDIS_PORT.
SESSION_REDIS_UNIX_DOMAIN_SOCKET_PATH = '/var/run/redis/redis.sock'

配置完结后可测试如下:

$ pip install django nose redis
# Make sure you have redis running on localhost:6379
(poem)[beginman@beginman poem]$ nosetests

----------------------------------------------------------------------
Ran 0 tests in 0.001s

OK
d、为数量表添加搜索效率

882828九五至尊手机版 199882828九五至尊手机版 200

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')

admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

2> 配置django-redis-sessions

在settings.py中配置

CACHES = {
        "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": [
                "redis://:password@IP0.0.0.0:6379",
            ],
            "OPTIONS": {
                # "CLIENT_CLASS": "django_redis.client.DefaultClient",
                "CONNECTION_POOL_KWARGS": {"max_connections": 100},     # 连接池
            }
        }
    }

882828九五至尊手机版 201882828九五至尊手机版 202

CACHES = {
    'default': {
        'BACKEND': 'redis_cache.RedisCache',
        'LOCATION': '<host>:<port>',
        'OPTIONS': {
            'DB': 1,
            'PASSWORD': '',
            'PARSER_CLASS': 'redis.connection.HiredisParser',
            'CONNECTION_POOL_CLASS': 'redis.BlockingConnectionPool',
            'CONNECTION_POOL_CLASS_KWARGS': {
                'max_connections': 50,
                'timeout': 20,
            }
        },
    },
}

View Code

e、添加非常快过滤

882828九五至尊手机版 203882828九五至尊手机版 204

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
    list_filter = ('username', 'email')



admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

更多:https://docs.djangoproject.com/en/1.11/ref/contrib/admin/

 

 

继续更新中……

3>django实现redis的存取
# Start by importing your default cache:
from django.core.cache import cache

# Store data under a-unique-key:
cache.set('a-unique-key', 'this is a string which will be cached')

# Later on you can retrieve it in another function:
cache.get('a-unique-key') # Will return None if key is not found in cache

# You can specify a default value:
cache.get('another-unique-key', 'default value')

# You can store multiple values at once:
cache.set_many({'a': 1, 'b': 2, 'c': 3})

# And fetch multiple values:
cache.get_many(['a', 'b', 'c']) # returns {'a': 1, 'b': 2, 'c': 3}

# You can store complex types in the cache:
cache.set('a-unique-key', {
    'string'    : 'this is a string',
    'int'       : 42,
    'list'      : [1, 2, 3],
    'tuple'     : (1, 2, 3),
    'dict'      : {'A': 1, 'B' : 2},
})

更多:http://niwinz.github.io/django-redis/latest/\#\_installation 

 

十三、缓存

鉴于Django是动态网站,全数每便请求均会去数据开展对应的操作,当程序访问量大时,耗费时间自然会越加显眼,最简便易行化解措施是应用:缓存,缓存将1个某部views的再次回到值保存至内部存款和储蓄器依旧memcache中,肆分钟内再有人来做客时,则不再去执行view中的操作,而是直接从内部存款和储蓄器还是Redis中在此以前缓存的情节获得,并回到。

Django中提供了6种缓存格局:

  • 开发调节和测试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

1、配置

a、开发调节和测试

882828九五至尊手机版 205882828九五至尊手机版 206

# 此为开始调试用,实际内部不做任何操作
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.dummy.DummyCache',     # 引擎
                'TIMEOUT': 300,                                               # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
                'OPTIONS':{
                    'MAX_ENTRIES': 300,                                       # 最大缓存个数(默认300)
                    'CULL_FREQUENCY': 3,                                      # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                },
                'KEY_PREFIX': '',                                             # 缓存key的前缀(默认空)
                'VERSION': 1,                                                 # 缓存key的版本(默认1)
                'KEY_FUNCTION' 函数名                                          # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
            }
        }


    # 自定义key
    def default_key_func(key, key_prefix, version):
        """
        Default function to generate keys.

        Constructs the key used by all other methods. By default it prepends
        the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
        function with custom key making behavior.
        """
        return '%s:%s:%s' % (key_prefix, version, key)

    def get_key_func(key_func):
        """
        Function to decide which key function to use.

        Defaults to ``default_key_func``.
        """
        if key_func is not None:
            if callable(key_func):
                return key_func
            else:
                return import_string(key_func)
        return default_key_func

View Code

b、内存

882828九五至尊手机版 207882828九五至尊手机版 208

# 此缓存将内容保存至内存的变量中
    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                'LOCATION': 'unique-snowflake',
            }
        }

    # 注:其他配置同开发调试版本

View Code

c、文件

882828九五至尊手机版 209882828九五至尊手机版 210

# 此缓存将内容保存至文件
    # 配置:

        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
                'LOCATION': '/var/tmp/django_cache',
            }
        }
    # 注:其他配置同开发调试版本

View Code

d、数据库

882828九五至尊手机版 211882828九五至尊手机版 212

# 此缓存将内容保存至数据库

    # 配置:
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                'LOCATION': 'my_cache_table', # 数据库表
            }
        }

    # 注:执行创建表命令 python manage.py createcachetable

View Code

e、Memcache缓存(python-memcached模块)

882828九五至尊手机版 213882828九五至尊手机版 214

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

f、Memcache缓存(pylibmc模块)

882828九五至尊手机版 215882828九五至尊手机版 216

# 此缓存使用pylibmc模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': '/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
        }
    }

View Code

 

2、应用

a、 全站使用

882828九五至尊手机版 217882828九五至尊手机版 218

使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存

    MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中间件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""

View Code

b、单独视图缓存

882828九五至尊手机版 219882828九五至尊手机版 220

方式一:
        from django.views.decorators.cache import cache_page

        @cache_page(60 * 15)
        def my_view(request):
            ...

    方式二:
        from django.views.decorators.cache import cache_page

        urlpatterns = [
            url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
        ]

View Code

c、局地视图使用

882828九五至尊手机版 221882828九五至尊手机版 222

a. 引入TemplateTag

        {% load cache %}

    b. 使用缓存

        {% cache 5000 缓存key %}
            缓存内容
        {% endcache %}

View Code

更多:撞击那里

 

 

十四、序列化

关于Django中的系列化重要行使在将数据库中找找的数据重回给客户端用户,越发的Ajax请求一般重返的为Json格式。

1、serializers

from django.core import serializers

ret = models.BookType.objects.all()

data = serializers.serialize("json", ret)

2、json.dumps

import json

#ret = models.BookType.objects.all().values('caption')
ret = models.BookType.objects.all().values_list('caption')

ret=list(ret)

result = json.dumps(ret)

出于json.dumps时无法处理datetime日期,所以能够通过自定义处理器来做扩充,如:

882828九五至尊手机版 223882828九五至尊手机版 224

import json 
from datetime import date 
from datetime import datetime 

class JsonCustomEncoder(json.JSONEncoder): 

    def default(self, field): 

        if isinstance(field, datetime): 
            return o.strftime('%Y-%m-%d %H:%M:%S') 
        elif isinstance(field, date): 
            return o.strftime('%Y-%m-%d') 
        else: 
            return json.JSONEncoder.default(self, field) 


# ds = json.dumps(d, cls=JsonCustomEncoder) 

View Code

 

 

十五、中间件

django
中的中间件(middleware),在django中,中间件其实就是三个类,在呼吁到来和终止后,django会依照自身的条条框框在适合的火候执行中间件中相应的主意。

在django项目的settings模块中,有一个
MIDDLEWARE_CLASSES 变量,在那之中各类因素便是三当中间件,如下图。

882828九五至尊手机版 225

与mange.py在平等目录下的文书夹
wupeiqi/middleware下的auth.py文件中的Authentication类

中间件中能够定义八个办法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args,
    callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

以上办法的再次来到值能够是None和HttpResonse对象,如若是None,则持续依照django定义的规则向下进行,如果是HttpResonse对象,则直接将该对象回来给用户。

882828九五至尊手机版 226

自定义中间件

一 、创造中间件类

class RequestExeute(object):

    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        i =1
        pass
    def process_exception(self, request, exception):
        pass

    def process_response(self, request, response):
        return response

二 、注册中间件

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'wupeiqi.middleware.auth.RequestExeute',
)

 

 

十六、信号

Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,正是局地动作发生的时候,信号允许特定的发送者去提示部分接受者。

壹 、Django内置信号

Model signals
    pre_init                    # django的modal执行其构造方法前,自动触发
    post_init                   # django的modal执行其构造方法后,自动触发
    pre_save                    # django的modal对象保存前,自动触发
    post_save                   # django的modal对象保存后,自动触发
    pre_delete                  # django的modal对象删除前,自动触发
    post_delete                 # django的modal对象删除后,自动触发
    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
    pre_migrate                 # 执行migrate命令前,自动触发
    post_migrate                # 执行migrate命令后,自动触发
Request/response signals
    request_started             # 请求到来前,自动触发
    request_finished            # 请求结束后,自动触发
    got_request_exception       # 请求异常后,自动触发
Test signals
    setting_changed             # 使用test测试修改配置文件时,自动触发
    template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
    connection_created          # 创建数据库连接时,自动触发

对于Django内置的信号,仅需注册内定信号,当程序执行相应操作时,自动触发注册函数:

882828九五至尊手机版 227882828九五至尊手机版 228

from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception

    from django.db.models.signals import class_prepared
    from django.db.models.signals import pre_init, post_init
    from django.db.models.signals import pre_save, post_save
    from django.db.models.signals import pre_delete, post_delete
    from django.db.models.signals import m2m_changed
    from django.db.models.signals import pre_migrate, post_migrate

    from django.test.signals import setting_changed
    from django.test.signals import template_rendered

    from django.db.backends.signals import connection_created


    def callback(sender, **kwargs):
        print("xxoo_callback")
        print(sender,kwargs)

    xxoo.connect(callback)
    # xxoo指上述导入的内容

View Code

882828九五至尊手机版 229882828九五至尊手机版 230

from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

View Code

二 、自定义信号

a. 定义信号

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 注册信号

def callback(sender, **kwargs):
    print("callback")
    print(sender,kwargs)

pizza_done.connect(callback)

c. 触发信号

from 路径 import pizza_done

pizza_done.send(sender='seven',toppings=123, size=456)

鉴于放置信号的触发者已经集成到Django中,所以其会自行调用,而对此自定义信号则须求开发者在任意地点触发。

更多:相撞那里

 

 

十七、admin

django
amdin是django提供的四个后台管理页面,改管理页面提供周密的html和css,使得你在通过Model创设完数据库表之后,就足以对数据开始展览增加和删除改查,而利用django
admin 则供给以下步骤:

  • 创办后台管理员
  • 配置url
  • 登记和配置django admin后台管理页面

一 、创立后台管理员

python manage.py createsuperuser

二 、配置后台管理url

url(r'^admin/', include(admin.site.urls))

叁 、注册和配置django admin 后台管理页面

a、在admin中实践如下配置

882828九五至尊手机版 231882828九五至尊手机版 232

from django.contrib import admin

from app01 import  models

admin.site.register(models.UserType)
admin.site.register(models.UserInfo)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

b、设置数据表名称

882828九五至尊手机版 233882828九五至尊手机版 234

class UserType(models.Model):
    name = models.CharField(max_length=50)

    class Meta:
        verbose_name = '用户类型'
        verbose_name_plural = '用户类型'

View Code

c、打开表之后,设定暗许呈现,需求在model中作如下配置

882828九五至尊手机版 235882828九五至尊手机版 236

class UserType(models.Model):
    name = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

View Code

882828九五至尊手机版 237882828九五至尊手机版 238

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')


admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

d、为数量表添加搜索效果

882828九五至尊手机版 239882828九五至尊手机版 240

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')

admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

e、添加速捷过滤

882828九五至尊手机版 241882828九五至尊手机版 242

from django.contrib import admin

from app01 import  models

class UserInfoAdmin(admin.ModelAdmin):
    list_display = ('username', 'password', 'email')
    search_fields = ('username', 'email')
    list_filter = ('username', 'email')



admin.site.register(models.UserType)
admin.site.register(models.UserInfo,UserInfoAdmin)
admin.site.register(models.UserGroup)
admin.site.register(models.Asset)

View Code

更多:http://docs.30c.org/djangobook2/chapter06/

 

 

 

相关文章

Your Comments

近期评论

    功能


    网站地图xml地图