Model
到目前为止, 当我们的程序涉及到数据库相关操作时, 我们一般都会这么搞:
创建数据库, 设计表结构和字段
使用 MySQLdb 来连接数据库, 并编写数据访问层代码
业务逻辑层去调用数据访问层执行数据库操作
View Code
django 为使用一种新的方式, 即: 关系对象映射(Object Relational Mapping, 简称 ORM)
- PHP:activerecord
- Java:Hibernate
- C#:Entity Framework
django 中遵循 Code Frist 的原则, 即: 根据代码中定义的类来自动生成数据库表
一创建表
1 基本结构
- from django.db import models
- class userinfo(models.Model):
- name = models.CharField(max_length=30)
- email = models.EmailField()
- memo = models.TextField()
字段
参数
元信息
拓展知识
2 连表结构
一对多: models.ForeignKey(其他表)
多对多: models.ManyToManyField(其他表)
一对一: models.OneToOneField(其他表)
应用场景:
一对多: 当一张表中创建一行数据时, 有一个单选的下拉框(可以被重复选择)
例如: 创建用户信息时候, 需要选择一个用户类型普通用户金牌用户铂金用户等
多对多: 在某表中创建一行数据是, 有一个可以多选的下拉框
例如: 创建用户信息, 需要为用户指定多个爱好
一对一: 在某表中创建一行数据时, 有一个单选的下拉框(下拉框中的内容被用过一次就消失了
例如: 原有含 10 列数据的一张表保存相关信息, 经过一段时间之后, 10 列无法满足需求, 需要为原来的表再添加 5 列数据
字段以及参数
二操作表
1 基本操作
基本操作
2 进阶操作(了不起的双下划线)
利用双下划线将字段和对应的操作连接起来
进阶操作
3 其他操作
其他操作
4 连表操作(了不起的双下划线)
利用双下划线和 _set 将表之间的操作连接起来
表结构实例
一对一操作
一对多
多对多操作
扩展:
a 自定义上传
View Code
bForm 上传文件实例
Form
Model
View
Form
django 中的 Form 一般有两种功能:
输入 html
验证用户输入
Form
View
扩展: ModelForm
在使用 Model 和 Form 时, 都需要对字段进行定义并指定类型, 通过 ModelForm 则可以省去 From 中字段的定义
View Code
跨站请求伪造
一简介
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 普通表单
- + View Code
- 2Ajax
对于传统的 form, 可以通过表单的方式将 token 再次发送到服务端, 而对于 ajax 的话, 使用如下方式
- view.py
- + View Code
- text.html
- + View Code
更多: https://docs.djangoproject.com/en/dev/ref/csrf/#ajax
Cookie
1 获取 Cookie:
- request.COOKIES[key]
- request.get_signed_cookie(key, default=RAISE_ERROR, salt=, max_age=None)
参数:
default: 默认值
salt: 加密盐
max_age: 后台控制过期时间
2 设置 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 hasnt been already.)
path=/, Cookie 生效的路径,/ 表示根路径, 特殊的: 跟路径的 cookie 可以被任何 url 的页面访问
domain=None, Cookie 生效的域名
secure=False, https 传输
httponly=False 只能 http 协议传输, 无法被 JavaScript 获取(不是绝对, 底层抓包可以获取到也可以被覆盖)
由于 cookie 保存在客户端的电脑上, 所以, JavaScript 和 jquery 也可以操作 cookie
- =/static/js/jquery.cookie.js>
- $.cookie("list_pager_num", 30,{ path: / });
- Session
Django 中默认支持 Session, 其内部提供了 5 种类型的 Session 供开发者使用:
数据库(默认)
缓存
文件
缓存 + 数据库
加密 cookie
1 数据库 Session
+ View Code
2 缓存 Session
+ View Code
3 文件 Session
+ View Code
4 缓存 + 数据库 Session
+ View Code
5 加密 cookie Session
+ 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
分页
一 Django 内置分页
views.py
Html
扩展内置分页: views.py
扩展内置分页: Html
二自定义分页
分页功能在每个网站都是必要的, 对于分页来说, 其实就是根据用户的输入计算出应该在数据库表中的起始位置
1 设定每页显示数据条数
2 用户输入页码(第一页第二页...)
3 根据设定的每页显示条数和当前页码, 计算出需要取数据表的起始位置
4 在数据表中根据起始位置取值, 页面上输出数据
需求又来了, 需要在页面上显示分页的页面如:[上一页][1][2][3][4][5][下一页]
1 设定每页显示数据条数
2 用户输入页码(第一页第二页...)
3 设定显示多少页号
4 获取当前数据总条数
5 根据设定显示多少页号和数据总条数计算出, 总页数
6 根据设定的每页显示条数和当前页码, 计算出需要取数据表的起始位置
7 在数据表中根据起始位置取值, 页面上输出数据
8 输出分页 html, 如:[上一页][1][2][3][4][5][下一页]
分页实例
总结, 分页时需要做三件事:
创建处理分页数据的类
根据分页数据获取数据
输出分页 HTML, 即:[上一页][1][2][3][4][5][下一页]
缓存
由于 Django 是动态网站, 所有每次请求均会去数据进行相应的操作, 当程序访问量大时, 耗时必然会更加明显, 最简单解决方式是使用: 缓存, 缓存将一个某个 views 的返回值保存至内存或者 memcache 中, 5 分钟内再有人来访问时, 则不再去执行 view 中的操作, 而是直接从内存或者 Redis 中之前缓存的内容拿到, 并返回
Django 中提供了 6 种缓存方式:
开发调试
内存
文件
数据库
Memcache 缓存(python-memcached 模块)
Memcache 缓存(pylibmc 模块)
1 配置
a 开发调试
View Code
b 内存
View Code
c 文件
View Code
d 数据库
View Code
eMemcache 缓存(python-memcached 模块)
View Code
fMemcache 缓存(pylibmc 模块)
View Code
2 应用
a. 全站使用
View Code
b. 单独视图缓存
View Code
c 局部视图使用
View Code
更多: 猛击这里
序列化
关于 Django 中的序列化主要应用在将数据库中检索的数据返回给客户端用户, 特别的 Ajax 请求一般返回的为 Json 格式
- 1serializers
- from django.core import serializers
- ret = models.BookType.objects.all()
- data = serializers.serialize("json", ret)
- 2json.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 日期, 所以可以通过自定义处理器来做扩展, 如:
+ View Code
信号
Django 中提供了信号调度, 用于在框架执行操作时解耦通俗来讲, 就是一些动作发生的时候, 信号允许特定的发送者去提醒一些接受者
1Django 内置信号
- 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 内置的信号, 仅需注册指定信号, 当程序执行相应操作时, 自动触发注册函数:
View Code
View Code
2 自定义信号
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 中, 所以其会自动调用, 而对于自定义信号则需要开发者在任意位置触发
更多: 猛击这里
来源: http://www.bubuko.com/infodetail-2529690.html