python 学习笔记(十二)--Django 基本知识点小结
1.Django中的相应对象
构造函数格式:
HttpResponse(content=响应体,content_type=响应体数据类型,status=状态码)
作用:
向客户端浏览器返回相应,同时携带响应体内容。
参数:
--content:表示返回的内容。
--status_code:返回的HTTP响应状态码(默认为200)。
--content_type:指定返回数据的MIME类型(默认为“text/html”)。浏览器会根据这个属性,来显示数据。如果是text/html,那么就会解析这个字符串,如果是text/plain,那么就会显示一个纯文本。
响应头中常见的Content-Type:
-- text/html :默认的,html文件
--text/plain:纯文本
--text/css:css文件
--text/javascript:js文件
--multipart/form-data:文件提交
--application/json:json传输
--application/xml:xml文件
2.GET处理
request.GET['参数名'] ##QueryDict
request.GET.get('参数名','默认值')
request.GET.getlist('参数名')
3.模板
(1)模板是可以根据字典数据动态变化的html网页。
(2)模板可以根据视图中传递的字典数据动态生成相应的HTML网页。
(3)创建模板文件夹,一般位于<项目名>/templates
(4)在settings.py中,TEMPLATES的配置项:
"BACKEND":指定模板的引擎。
"DIRS":模板的搜索目录(可以是一个或者多个)
"APP_DIRS":是否要在应用中的templates文件夹中搜索模板文件。
OPTIONS":有关模板的选项。
4.模板的加载
方案1
通过loader获取模板,通过HttpResponse进行响应。注意是在视图函数中实现。
例如
from django.template import loader #1 通过loader加载模板 t = loader.get_template("模板文件名") #2 将t转换成HTML字符串 html = t.render(字典数据) #3 用响应对象将转化的字符串内容返回给浏览器 return HttpResponse(html)
方案2,也是常用的方法
使用render(()直接加载并相应模板。注意是在视图函数中实现。
from django.shortcuts import render, get_object_or_404 return render(request, "模板文件名", 字典数据)
5.视图层与模板层之间的交互
(1).视图函数中,可以将Python变量封装到字典中,然后传递大模板。
例如
context = { "active_user": active_user, "group_list": group_list, "enable_backup_switch": config.get("enable_backup_switch"), } return render(request, "XXXX.html", context)
(2).模板中,我们可以用{{ 变量名 }}的语法,调用视图传进来的变量。
6.模板的变量
(1)能传递到模板中的数据类型
str --字符串 int ---整型
list --数组 tuple --元组
dict--字典 func--方法
obj --类实例化的对象
(2)在模板中使用变量语法
--{{ 变量名 }}
--{{ 变量名.index }} ---例如传递过来的变量是list
--{{ 变量名.key }} ---例如传递过来的变量是字典
--{{ 对象.方法 }}
--{{ 函数名 }}
7.模板过滤器
定义:在变量输出时对变量的值进行处理
作用:可以通过使用 过滤器 来改变变量的输出显示
语法:
{{ 变量名 | 过滤器1:可选参数1 | 过滤器2:可选参数2 ... }}
8.模板的继承
模板继承可以使父模板的内容重用,子模版直接继承父模板的全部内容并可以覆盖父模板中相应的块。
语法--父模板中:
(1)定义父模板中的块block标签;
(2)标识出哪些在子模块中是允许被修改的;
(3)block标签:在父模板中定义,可以在子模版中覆盖,
语法--子模版中:
(1)继承模板extends 标签(写在模板文件的第一行)
例如 {% extends "base.html" %}
(2)子模版 重写父模板中的内容块
{% block block_name %}
子模版块用来覆盖父模板块中 block_name 块的内容
{% endblock block_name %}
9.代码中URL出现的位置
(1)模板【html】中的url
A.<a href='url'>超链接</a>
点击后,页面跳转至url
B.<from action = 'url' method = 'post'>
from 表单中的数据,用post方法提交至url
(2)视图函数中--302跳转,HttpResponseRedirect('url')
将用户地址栏中的地址跳转到url。
10.url反向解析
url反向解析是指在视图或模板中,用path定义的名称来动态查找或者计算出相应的路由。
path函数的语法
path(route,views,name="别名")
例如:
path('page',views.page_vies,name="page_url")
根据path中的'name='关键字传参给url确定了个唯一确定的名字,在模板
或视图中,可以通过这个名字反向推断出此url信息。
模板中使用,通过url标签实现地址的方向解析:
{% url '别名'%}
{% url '别名' '参数值1' '参数值2' %}
在视图函数中使用,可调用django中的reverse方法进行反向解析。
from django.urls import reverse
reverse('别名',args=[],kwargs={})
11.静态文件配置
* 静态文件配置位于settings.py中。
配置静态文件的访问路径【配置默认存在】
# Static files (CSS, JavaScript, Images) STATIC_URL = "/static/" STATIC_ROOT = os.path.join(BASE_DIR, "static") STATICFILES_DIRS = [ os.path.join(BASE_DIR, "common/static"), ] STATICFILES_STORAGE = "common.storage.ForgivingManifestStaticFilesStorage"
说明:(1)指定访问静态文件时是需要通过/static/xxx或http://127.0.0.1:80/static/xxx.
[xxx表示具体的静态资源位置];
(2)STATICFILES_DIRS ---保存的是静态文件在服务器端的存储位置。
12.Django中的应用
应用在Django项目中是一个独立的业务模块,可以包含自己的路由、视图、模板、模型。
(1)创建应用
step 1 用manage.py 中的子命令startapp 创建应用文件夹
python manage.py startapp XXXX
step 2 在settings.py 的INSTALLED_APPS = ()列表中配置安装此应用。
13.分布式路由
Django中,主路由配置文件(urls.py)可以不处理用户具体路由,主路由配置文件可以做请求的分发(分布式请求处理)。具体的请求可以由各自的应用来进行处理。
配置分布式路由
step 1 --主路由中调用include函数
导入的模块
from django.urls import include, path
语法:include('app名字.url 模块名')
作用:用于将当前路由转到各个应用的路由配置文件的urlpatterns进行分布式处理。
例如 archery项目中的分布式配置。
urlpatterns = [ path("admin/", admin.site.urls), path("api/", include(("sql_api.urls", "sql_api"), namespace="sql_api")), path("", include(("sql.urls", "sql"), namespace="sql")), ]
14 应用下的模板
应用内部可以配置模板目录
(1)应用下手动创建templates文件夹;
(2)settings.py中 开启 应用模板功能,TEMPLATES 配置项中的"APP_DIRS": True 即可。
应用下templates 和外层templates都存在是,django的查找模板规则:
(1)优先查找外层templates目录下的模板;
(2)按# Application definition 中 INSTALLED_APPS 配置下的 应用顺序,逐层查找。
15 什么是模型
模型是一个Python类,它是由django.db.models.Model派生出的子类。
一个模型类代表数据库中的一张数据表。
模型类中每一个类属性都代表数据库中的一个字段。
模型是数据交互的接口,是表示和操作数据库的方法和方式。
16.ORM框架
定义: ORM(Object Relational Mapping)即对象关系映射,它是一种程序技术,它允许你使用类和对象对数据库进行操作,从而避免通过SQL语句操作数据库。
作用:
(1)建立模型类和表之间的对应关系,允许我们通过面向对象的方式来操作数据库。
(2)根据设计的模型类生成数据库中的表。
(3)通过简单的配置就可以进行数据库的部署或DB类型的切换。
有点:
(1)只需要面向对象编程,不需要面向数据库编写代码。
对数据库的操作都转化成对类属性和方法的操作;不用编写各种数据库的SQL语句。
(2)实现了数据库模型与数据库的解耦,屏蔽了不同数据库操作上的差异。
不再关注于用的是MySQL、Oracle。。。等数据库的内部细节;通过简单的配置就可以轻松更换数据库,而不需要修改代码。
缺点:
对于复杂业务,使用成本较高;
根据对象的操作转换成SQL语句,根据查询的结果转换成对象,在映射过程中有性能损失。
17.模型--数据库迁移
迁移是Django同步您对数据库所做的更改(添加字段、删除模型等)到您的数据库模型的方式。
(1)生成迁移文件,执行 python manage.py makemigrations ,将应用下的models.py文件生成一个中间文件,并保存在migrations文件夹中。
(2)执行迁移脚本程序,--执行 python manage.py migrate ,执行迁移程序实现迁移。将每个应用下的makemigrations目录中的中间文件同步回数据库。
18. 模型---字段类型
常见字段类型相关说明补充如下:
字段类型 | 编程语言 | 数据库语言 | 备注 |
BooleanField() | 使用True或False来表示值。 |
tinyint(1) |
在数据库中,使用1或0来表示具体的值。 |
NullBooleanField() |
可以为空的布尔值。 | ||
CharField(Field) | varchar() | 必须提供max_length参数, max_length表示字符长度 | |
DateField() | 表示日期 | date |
参数: auto_now:每次保存对象时,自动设置该字段为当前时间(取值:True/False); auto_now_add:当对象第一次被创建时自动设置当前时间(取值:True/False); default:设置当前时间(取值:字符串格式时间,如:'2019-10-15'); 以上三个参数只能多选一。 |
DateTimeField() | 表示日期和时间 | datetime(6) |
参数同DateField. |
DecimalField() | 使用小数表示该列的值 |
使用小数 decimal(x,y) |
参数: max_digits,小数总长度【位数总数】,包括小数点后的位数,该值必须大于等于decimal_places; decimal_places,小数位长度【小数点后的数字数量】。 |
FloatField() | 浮点型 | double | 编程语言中和数据库中都使用小数表示值。 |
EmailField() | 字符串类型 | varchar |
Django Admin以及ModelForm中提供验证机制。 编程语言和数据库中使用字符串。 |
IPAddressField() | 字符串类型 | Django Admin以及ModelForm中提供验证 IPV4 机制 | |
GenericIPAddressField() |
字符串类型 |
Django Admin以及ModelForm中提供验证 Ipv4和Ipv6。 参数:
|
|
IntegerField() | 整数列 | int |
编程语言和数据库中使用整数。 |
SmallIntegerField() | 小整数 - 32768 ~ 32767 |
||
BigIntegerField() | 长整型(有符号的) - 9223372036854775808 ~ 9223372036854775807 |
||
ImageField() | 字符串 | varchar(100) |
在数据库中为了保存图片的路径【路径保存在数据库中,文件上传到指定目录】。 编程语言和数据库中使用字符串。 参数:
|
TextField() | 文本类型 | longtext |
表示不定长的字符数据。 |
19. 模型 --字段选项
字段选项时指创建列时指定的额外的信息。允许出现多个字段选项,多个选项之间用【,】隔开。
字段选项 | 作用描述 |
primary_key |
如果设置为True,表示该列为主键,如果指定一个字段为主键,则此表不会再自动创建id字段。 |
blank |
Admin中是否允许用户输入为空 表单提交时可以为空。 设置为True时,字段可以为空;设置为False时,字段则必须填写。 |
null |
如果设置为True,表示该列值允许为空。默认为False,如果此选项为False,建议加入default选项来设置默认值。 |
default |
数据库中字段的默认值。 设置所在列默认值,如果字段选项null=False,建议添加此项。 |
db_index | 数据库中字段是否可以建立索引(db_index = True )。如果为True,表示为该列增加索引。 |
unique |
|
db_column | 字段的列名。指定列的名称,如果不指定的话则采用属性名称作为列名。 |
verbose_name | Admin中显示的字段名称。设置此字段在admin界面上的显示名称。 |
choices | Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作。 |
error_messages | 自定义错误信息(字典类型),从而定制想要显示的错误信息。 |
validators | 自定义错误验证(列表类型),从而定制想要的验证规则。 |
20 模型--Meta类
使用内部Meta类来给模型赋予属性,Meta类下有很多内建的类属性,可以对模型类做一些控制。
部分属性说明如下:
属性 | 属性说明 |
managed | 因为Django会自己主动依据模型类生成映射的数据库表。假设你不希望Django这么做。能够把managed的值设置为False。 |
db_table |
db_table是用于指定自己定义数据库表名的。Django有一套默认的依照一定规则生成数据模型相应的数据库表名。假设你想使用自己定义的表名,就通过这个属性指定。 |
verbose_name | 给模型类起一个更可读的名字。 |
verbose_name_plural | 这个选项是指定。模型的复数形式是什么。 |
db_tablespace |
有些数据库有数据库表空间,比方Oracle。通过db_tablespace来指定这个模型相应的数据库表放在哪个数据库表空间。 |
unique_together | unique_together这个选项用于:当你须要通过两个字段保持唯一性时使用。 |
abstract |
这个属性是定义当前的模型类是不是一个抽象类。所谓抽象类是不会相应数据库表的。一般我们用它来归纳一些公共属性字段,然后继承它的子类能够继承这些字段。 |
permissions |
permissions主要是为了在Django Admin管理模块下使用的。设置这个属性能够让指定的方法权限描写叙述更清晰可读。 |
ordering | 这个字段是告诉Django模型对象返回的记录结果集是依照哪个字段排序的。 |
在此,补充一个model的知识点,与Meta无关,就是__str__(self)方法。可以在模型类中定义__str__方法,自定义QuerySet中的输出格式。这样可视化程度更高,方便调试。
21.ORM--操作
基本操作包括增删改查操作,即CRUD操作。
CRUD是指在做计算处理时的增加(Create)、读取查询(Read)、更新(Update)和删除(Delete)。
ORM CRUD 核心--> 模型类.管理器对象。
每个继承自models.Model的模型类,都会有一个objects对象被同样继承下来。这个 对象叫管理器对象。
数据库的增删改查可以通过模型的管理器实现。
class MyModel(models.Model): .... MyModel.objects.create(...) ##objects 是管理器对象
创建数据
Django ORM 使用一种直观的方式把数据库表中的数据表示成Python对象。
创建数据中每一条记录就是创建一个数据对象。
方案1
MyModel.objects.create(属性1=值1,属性2=值2)
成功:返回创建好的实体对象;失败:抛出异常。
方案2
创建MyModel实例对象,并调用save()进行保存。
obj = MyModel(属性=值,属性=值)
obj.属性=值
obj.save()
22.查询简介
数据库的查询需要使用管理器对象进行,通过MyModel.objects管理方法调用查询方法。
查询方法 | 用法 | 作用 | 等同于SQL | 返回值 | 简单举例 |
all() | MyModel.objects.all() | 查询MyModel实体中所有所有的数据。 | select*from table | QuerySet 容器对象[类似数组],内部存放MyModel实例 |
books =Book.objects.all() for book in books: print("书名",book.title,'出版社:' book.pub) |
values(’列1‘,’列2‘) | MyModel.objests.values(...) | 查询部分列的数据并返回 | select列1,列2 from table |
QuerySet.返回查询结果容器,容器内存字典,每个字典代表一条数据。格式为:{’列1‘:值1,’列2‘:值2} |
a2=Book.objects.values('title','pub') for book in a2 print(book[title]) |
values_list('列1','列2'...) | MyModel.objects.values_list(...) | 返回元组形式的查询结果 | select 列1,列2 from table | QuerySet 容器对象,内部存放’元组‘。会将查询出来的数据封装到元组中,再封装到查询集合QuerySet中。 |
a3 = Book.objects.values_list('title','pub') for book in a3: print(book[0]) |
order_by() | MyModel.objects.order_by('-列','列') | 与all()方法不同,它会用sql语句的order by 子句对查询结果进行根据指定字段选择性的进行排序。 |
默认是按照升序排序,降序排序则需要在列前增加’-‘表示。 可以和其它查询方法组合使用。 |
||
filter(条件) | MyModel.objects.filter(属性1=值1,属性2=值2) | 返回符合此条件的全部的数据集 | QuerySet容器对象,内部存放MyModel实例 |
当多个属性在一起时为”与“关系。 books = Book.objects.filter(pub="清华大学出版社") for book in books: print("书名",book.title) |
|
exclude(条件) | MyMOdel.objects.exclude(条件) | 返回不包含(不符合)此条件的全部的数据集 |
books = models.Book.objects.exclude(pub=”清华大学出版社“,price=50) for book in books: print(book) |
||
get(条件) | MyModel.objects.get(条件) | 返回满足条件的唯一一条数据 |
该方法只能返回一条数据。查询结果多余一条数据则抛出异常--Model.MultipleObjectsReturned异常。查询结果如果没有数据则抛出Model.DoesNotExist异常。 |
23.查询谓词
定义:做更灵活的条件查询时需要使用查询谓词。
说明:每一个查询谓词是一个独立的查询功能。
查询谓词 | 功能 | 举例 |
__exact | 等值匹配 |
Book.objects.filter(id__exact=1) ##等同于select * from books where id =1 |
__contains |
包含指定值. __startswith:以XXX开始; __endswith:以XXX结束。 |
Author.objects.filter(name__contains='w') ##等同于 select * from author where name like '%w%' |
__gt |
大于指定值; __gte:大于等于; __lt:小于 __lte:小于等于 |
Author.objects.filter(age__gt=50) ##等同于 select * from author where age>50 |
__in | 查找数据是否在指定范围内 |
Author.objects.fileter(country__in=['中国','韩国','越南']) ##等同于select * from author where country in ('中国','韩国',越南'') |
__range | 查找数据是否在指定的时间范围内 |
Author.objects.filter(age__range=(35,50)) ##等同于 select * from author where age between 35 and 50 |
24 ORM 更新操作
更新单个数据
修改单个实体的某些字段的步骤:
step 1. 查
通过get()等到要修改的实体对象;
step 2 改
通过 对象.属性 的方式 修改数据
step 3 保存
通过对象.save()保存数据
批量更新数据
直接调用QuerySet的update(属性=值)实现批量修改。
例如
##将id大于3的所有图书价格定为0元 books =Book.objects.filter(id__gt=3) books.update(price=0) ##返回成功执行影响的行数
25.ORM--删除操作
单个数据删除
步骤
step 1 查找
查询对应的数据对象
step 2 删除
调用这个数据对象的delete()方法进行删除。
try: auth=Author.objects.get(id=1) auth.delete() except: print(删除失败)
批量删除
step 1 查找
查询结果集中满足条件的全部QuerySet查询集合对象
step 2 调用查询集合对象的delete()方法实现删除
##删除全部作者中,年龄大于65的全部信息 auths = Author.objects.filter(age__gt=65) auths.delete()
26 F对象
定义:一个F对象代表数据库中某条记录的字段的信息。
作用:通常是对数据库中的字段值在不获取的情况下进行操作,用于类属性(字段)之间的比较。
语法:
from django.db.models import F F('列名')
示例:
更新Book实例中所有的零售价涨10元。
如果不用F对象,如下:
books = Book.objects.all() for book in books: book.market_price=book.marget_price+10 book.save()
使用F对象,可以简化如下:
Book.objects.all().update(market_price=F('market_price')+10)
实例2
对数据库中两个字段的值进行比较,例如,列出那些书的零售价高于定价?
books = Book.objects.filter(market_price__gt=F('price')) for book in books: print(book.title,'定价:',book.price,'现价:',book.market_price)
27.Q对象
当在获取查询结果集,使用复杂的逻辑或|、逻辑非~等操作时,可以借助于Q对象进行操作。
如,想找出定价低于20元或中国机械出版社的全部书,可以写成:
Book.objects.filter(Q(price__lt=20)|Q(pub="中国机械出版社"))
Q对象在数据包 django.db.models中,需要先导入再使用。
运算符:
& 与操作
| 或操作
~ 非操作
from django.db.models import Q Q(条件1)|Q(条件2) ##表示需要 条件1成立或者条件2成立; Q(条件1)&Q(条件2) ##条件1和条件2同时成立; Q(条件1)&~Q(条件2) ##条件1成立且条件2不成立。
28.聚合查询
整表聚合
不带分组的聚合查询是指将全部的数据进行集中统计查询。
聚合函数需要从django.db.models导入,常用的聚合函数:Sum、Avg、Count、Max、Min ---【注意:首字母大写】。
语法:
MyModel.objects.aggregate(自定义的结果变量名=聚合函数('列'))
返回结果:结果变量名和值组成的字典,格式为:{"结果变量名":值}
分组聚合
分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值值(当然也可以是平均值或总和),即为查询集的每一项生成集合。
语法:
QuerySet.annotate(自定义结果变量名=聚合函数('列'))
返回值:QuerySet。
简单来讲就是先通过MyModel.objects.values()进行查询,然后通过.annotate分组。
29.原生数据库操作
Django也支持之间用sql语句对数据库进行查询操作。
查询:使用MyModel.objects.raw()进行数据库查询操作。
语法:
MyModel.objects.raw(sql语句,拼接参数)
返回值:RawQuerySet集合对象【只支持基础操作,比如循环】
示例:
books = models.Book.objects.raw('select * from bookstore_book') for book in books: print(book)
使用原生语句时小心SQL注入。即 用户通过数据上传,将恶意的SQL语句提交给服务器,从而达到攻击效果。
30.原生数据库操作--cursor
可以支持查询、更新、删除。
step 1 导入cursor所在的包
from django.db import connection
step 2 用创建cursor类的构造函数创建cursor对象,再使用cursor对象,为保证在出现异常时能释放cursor资源,通常使用with语句进行创建操作。
from django.db import connection with connection.cursor() as cur: cur.execute('执行SQL语句','拼接参数')
31. admin管理后台
注册自定义模型类
若要自己定义的模型类也能在/admin后台管理界面中显示和管理,需要将自己的类注册到后台管理界面。
注册步骤:
step 1.在应用app中的admin.py中导入注册要管理的模型models类,如:
from .models import Book
step 2.调用admin.site.register方法进行注册,如
admin.site.register(自定义模型类)
模型管理器类
作用:为后台管理界面添加便于操作的新功能。
说明:管理后台类须继承自django.contrib.admin里的ModelAdmin类。
使用方法
step 1.在<应用app>/admin.py里定义模型管理类
class xxxxManager(admin.ModelAdmin):
......
step 2 绑定注册模型管理器和模型类
from django.contrib import admin from .models import * admin.site.register(YYYY,xxxxmanager) ###绑定YYYY模型类与管理器类xxxxManager
类xxxxManager 几个常用的属性
list_display = [] ##列表页显示那些字段的列;即去控制那些字段会显示在Admind显示列表中。
list_dispaly_links =[] ##控制list_display中的字段,那些可以链接到修改页;
list_filter=[] ##添加过滤器;即设置激活Admin修改列表页面右侧栏中的过滤器。
search_fields = [] ##添加搜索框;
list_editable = [] ##添加可在列表页编辑的字段,允许在更改列表页面上直接进行字段编辑。
32.Cookie
Cookies特点
(1)cookies在浏览器上是以键-值对的形式进行存储的,健和值都是以ASCII字符串的形式存储(不能是中文字符);(2)存储的数据带有生命周期;
(3)cookies中的数据都是按域【地址栏域名】存储隔离的,不同的域之间无法访问;
(4)cookies的内部的数据会在每次访问此网址时都会携带到服务器端,如果cookies过大会降低相应速度。
cookies的存储
HttpResponse.set_cookie(key,value='',max_age=None,expires=None)
--key,cookie的名字;
--value,cookie的值;
--max_age,cookie存活时间,秒为单位
--expires,具体过期时间;
--当不指定 max_age 和 expires 时,默认关闭浏览器时数据失效。
cookies的获取和删除
--获取,通过request.COOKIES绑定的字典(dict)获取客户端的cookies数据。
value = request.COOKIES.get('cookies名','默认值')
--删除,通过HttpResponse.delete_cookie(key)来删除指定的cookie。如果key不存在,则什么也不发生。
33.Session
session定义
session是在服务器上开辟一段空间用来保留浏览器和服务器交互时的重要数据。
session实现方式
使用session需要在浏览器客户端启动cookie,且在cookie中存储sessionid。每个客户端都可以在服务器端有一个独立的session。
注意:不同的请求者之间不会共享这个数据,是与请求者一一对应。
session初始配置
(1)向INSTALLED_APPS 列表中添加:
# Application definition INSTALLED_APPS = ( ##启用sessions 应用 "django.contrib.sessions", )
(2)向MIDDLEWARE 列表中添加:
MIDDLEWARE = ( ### 启用session 中间件 "django.contrib.sessions.middleware.SessionMiddleware", )
session的使用
session对象是一个类似于字典的SessionStore类型的对象,可以类似于字典的方式进行操作。
session能够存储如字符串、整型、字典、列表等。
(1) 保存session的值到服务器
request.session['key'] = value
(2) 获取session的值
value = request.session['key']
value = request.session.get('key',默认值)
(3)删除session
del request.session('key')
session在settings.py中相关配置项
# SESSION 设置 SESSION_COOKIE_AGE = 60 * 300 # 300分钟 SESSION_SAVE_EVERY_REQUEST = True SESSION_EXPIRE_AT_BROWSER_CLOSE = True # 关闭浏览器,则COOKIE失效
其它
Django 默认的session数据保存到数据库中,表为django_session。django_session表是单表设计,且该表数据量持续增加(浏览器故意删掉session或session过期,但其表数据并未删除)。可以执行python3 manage.py clearsessions [该命令可以删除已过期的session数据].
34.序列化
34.1 序列化组件
(1)序列化,序列化器会把模型对象转换成字典,经过Response()以后变成json字典;
(2)反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型;
(3)反序列化,可以完成数据校验功能。【找到这个对象--》得到一个序列化类的对象---》数据验证(序列化类的对象..is_valid())】
34.2 使用过程
(1)写一个模型;
(2)导入模型,写一个序列化的类,继承serializers.ModelSerializer,明确相应字段;
(3)完善相应的视图类,实例化得到序列化类的对象,把要序列化的对象导入;
(4)序列化类的对象.data ,是一个字典;
(5)把字典返回,使用from rest_framework.response import Response 中的Response;如果不使用这个 rest_framework中的Response,就要使用JsonResponse。
34.3 序列化组件修改数据
在执行保存数据 .save(),时,我们可能会收到 如下错误信息:
`update()` must be implemented.
这个报错是因为 程序的序列化 类 中没有定义 update() 方法,而是调用了基类rest_framework --》serializers--》BaseSerializer 中的update()方法。
def update(self, instance, validated_data): raise NotImplementedError('`update()` must be implemented.')
所以,可以在序列化类中自定义 update(self, instance, validated_data): 方法。
instance 可以粗略地理解为要修改的类对象, validated_data 可以粗略的理解为拿什么数据去修改。
注意 此时方法中的保存为
instance.save()