orm03
admin后台管理什么是admin后台管理
django提供了比较完善的后台数据库的接口,可供开辟过程中调用和测试使用
django会搜集所有已注册的模型类,为这些模型类提供数据管理界面,供开辟使用
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014232134371.png&pos_id=img-o4LVMJwK-1735482065158
admin配置步骤
创建后台管理账号
该账号为管理后台最高权限账号
[*]python3 manage.py createsuperuser
$ python3 manage. py createsuperuser
Username (leave blank to use 'root'): zhangsan # 此处输入用户名
Email address: zhangsan@1234.com # 此处输入邮箱
Password: # 此处输入密码(密码要复杂些,否则会提示密码太简单)
Password(again): # 再次输入重复密码
Superuser created successfully.
测试登录
启动服务后,后台管理的登录地点:http://127.0.0.1:8000/admin,使用刚才注册的管理员账号登录即可
实验:测试admin后台体系
[*] 首先创建用户,在终端执行 python3 manage.py createsuperuser 下令
(testenv) # python3 manage.py createsuperuser
用户名 (leave blank to use 'root'): root
电子邮件地址: root@qq.com
Password: 123456
Password (again): 123456
密码长度太短。密码必须包含至少 8 个字符。
这个密码太常见了。
密码只包含数字。
Bypass password validation and create user anyway? : y# 如果密码短需要手动确定
Superuser created successfully.
[*] 启动服务 django 服务
(testenv) # python3 manage.py runserver
[*] 后台管理的登录地点:http://127.0.0.1:8000/admin
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014232444344.png&pos_id=img-V9UfFy2L-1735482065161
注册自定义模型类
[*]若要自己定义的模型类也能在admin后台管理体系界面中显示和管理,需要将自己的类注册到后台管理界面
注册步骤
[*] 在应用app中的 admin.py 中导入注册要管理的模型 models 类,如:from .models import Book
[*] 调用 admin.site.register 方法举行注册,如:admin.site.register(自定义模型类)
[*] 案例
# file: bookstore/admin.py
from django. contrib import admin
# Register your models here.
from . import models
...
admin. site.register(models.Book)# 将Book类注册为可管理页面
[*] 修改自定义模型类的数据样式
[*] admin后台管理数据库中对自定义的数据记载都展示为 XXX object 类型的记载,不便于阅读和理解
[*] 在用户自定义的模型类中可以重写 def str(self)方法办理显示题目,如:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233358465.png&pos_id=img-GHd4W38O-1735482065162
实验:注册模型类
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014232820845.png&pos_id=img-aOetJvIZ-1735482065162
[*] 修改 bookstore 应用下的 admin.py 文件
from django.contrib import admin
# 方式一:引入模型模块,使用模型类: `models.模型类名`,例如 models.Book
# from . import models
# 方式二:直接导入模型类
from .models import Book
# Register your models here.
admin.site.register(Book)# 在模型类Book注册到站点admin,admin站点就会提供模型类Book的管理页面
[*] 启动服务,重新登录 admin 后台管理体系,观察界面
[*] https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233253734.png&pos_id=img-cx1hYpyo-1735482065162
[*] 点击Books链接,查看图书详情页
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233332443.png&pos_id=img-lt4YOuG3-1735482065162
[*] 这里显示的内容是 __str__ 方法封装的字符串,以是可以自定义修改显示的字段
[*] def __str __ (self):
return f'书名:{self.title},价格:{self.price},出版社:{self.pub},零售价:{self.market_price}'
[*] https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233613043.png&pos_id=img-ieVcnNXH-1735482065162
模型管理器类
理解与阐明
作用:为后台管理界面添加便于操作的新功能
阐明:后台管理器类须继承自 Django.contrib.admin 里的 ModelAdmin 类
使用方法
[*] 在 <应用app>/admin.py 里定义模型管理器类
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233743159.png&pos_id=img-oIvMnam5-1735482065162
[*] 绑定注册模型管理器和模型类
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233748062.png&pos_id=img-Q3WxY3d4-1735482065163
[*] 案例
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014233753397.png&pos_id=img-4iG5KG19-1735482065163
类属性阐明
[*]**list_display:**去控制哪些字段会显示在admin后台管理的修改列表页面中
[*]**list_display_links:**可以控制list_display中的字段是否应该链接到对象的”更改”页面
[*]**list_filter:**设置激活admin修改列表页面右侧栏中的过滤器
[*]**search_fields:**设置启用admin更改列表页面上的搜刮框
实验:绑定模型管理器类
[*] 修改 bookstore 应用下的 admin.py 文件,添加模型管理器类
from django.contrib import admin
from .models import Book
# 定义一个模型管理类
class BookManager(admin.ModelAdmin): # 后台管理器类须继承自Django.contrib.admin里的ModelAdmin类
# 列表页显示哪些字段的列
list_display = ["id", "title", "price", "market_price", "pub"]
# 控制 list_display 中的字段,哪些可以链接到修改页,缺省默认首列
list_display_links = ["title"] # 点击书名,可以进入该条数据的修改页面
# list_display_links = ["title", "price"] # 点击书名列或价格列,可以进入该条数据的修改页面
# 添加过滤器
list_filter = ["pub"] # 以出版社列给出过滤项
# 添加搜索框[模糊查询]
search_fields = ["title"] # 搜索框模糊匹配标题列
# search_fields = ["title", "pub"]# 搜索框模糊匹配书名列或出版社列
# 添加可直接在列表编辑的字段(不必进入修改页面)
list_editable = ["price"]
admin.site.register(Book, BookManager)# 将模型管理器类和模型类进行绑定
[*] 启动服务,重新登录 admin 后台管理体系,观察界面
[*] 点击Books进入详情页,发现修改内容均已在管理界面见效
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014234959521.png&pos_id=img-svR3GfVf-1735482065163
默认自带按字段排序功能
Meta类
在管理页面看见的模型类的名称,可以通过Meta内嵌类来修改。
通过Meta内嵌类定义模型类的属性,用法如下:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241014235152636.png&pos_id=img-Zybbipeu-1735482065163
实验:修改Meta类属性
[*] 修改 bookstore 应用下的 admin.py 文件,修改 Book 模型类
from django.db import models
class Book(models.Model):
title = models.CharField("书名", max_length=50, default="", unique=True)
pub = models.CharField("出版社", max_length=50, default="")
price = models.DecimalField("定价", max_digits=7, decimal_places=2, default=0.0)
market_price = models.DecimalField("零售价", max_digits=7, decimal_places=2, default=0.0)
is_active = models.BooleanField("是否活跃", default=True)
def __str__(self):
return f"{self.title}, {self.pub}, {self.price}, {self.market_price}"
class Meta:
db_table = "book"
verbose_name = "图书"# 修改单数显示
verbose_name_plural = verbose_name# 修改复数显示,缺省默认单数显示+s
[*] 启动服务,重新登录 admin 后台管理体系,观察界面
练习
需求:对 Author 模型管理类的自定义设置
[*]将 Author 模型类加入后台管理
[*]制作一个 AuthorManager 管理器类,让后台管理 Authors 列表中显示作者的 ID、姓名、年龄信息
[*]用后台管理程序添加三条 Author 记载
[*]修改其中一条记载的年龄 – Author
[*]删除最后一条添加的记载 – Author
修改bookstore 应用下的 admin.py 文件
from django.contrib import admin
from .models import Book,Author
# 定义一个模型管理类
class BookManager(admin.ModelAdmin): # 后台管理器类须继承自Django.contrib.admin里的ModelAdmin类
# 列表页显示哪些字段的列
list_display = ["id", "title", "price", "market_price", "pub"]
# 控制 list_display 中的字段,哪些可以链接到修改页,缺省默认首列
list_display_links = ["title"] # 点击书名,可以进入该条数据的修改页面
# list_display_links = ["title", "price"] # 点击书名列或价格列,可以进入该条数据的修改页面
# 添加过滤器
list_filter = ["pub"] # 以出版社列给出过滤项
# 添加搜索框[模糊查询]
search_fields = ["title"] # 搜索框模糊匹配标题列
# search_fields = ["title", "pub"]# 搜索框模糊匹配书名列或出版社列
# 添加可直接在列表编辑的字段(不必进入修改页面)
list_editable = ["price"]
class AuthorManager(admin.ModelAdmin):
list_display = ["id", "name", "age"]
list_display_links = ["name"]
admin.site.register(Book, BookManager)# 将模型管理器类和模型类进行绑定
admin.site.register(Author, AuthorManager)# 将模型管理器类和模型类进行绑定
修改 bookstore 应用下的 admin.py 文件,修改 Author 模型类
from django.db import models
class Author(models.Model):
...
class Meta:
db_table = "author"
verbose_name = "作者"# 修改单数显示
verbose_name_plural = verbose_name# 修改复数显示,缺省默认单数显示+s
总结
[*]注册自己的模型类
[*]修改自定义模型类的显示样式 - 模型管理器类
[*]Meta类对模型类的属性修改
用户管理
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015000236675.png&pos_id=img-knNxymtV-1735482065163
[*]权限
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015000359824.png&pos_id=img-LZ1TkQVV-1735482065164
关系映射
什么是关系映射
在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有:
[*]一对一映射
[*]如:一个身份证对应一个人
[*]一对多映射
[*]如:一个班级可以有多个学生
[*]多对多映射
[*]
[*]如:一个学生可以报多个课程,一个课程可以有多个学生学习
一对一映射 models.OneToOneField()
概念与理解
[*] 一对一是表示现实事物间存在的一对一的对应关系
[*] 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等
[*] 语法:OneToOneField(类名, on_delete=xxx)
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015223457954.png&pos_id=img-7SdXMZrY-1735482065164
特殊字段选项【必须】
on_delete:级联删除
[*] 几个可选的值:
[*] models.CASCADE:级联删除,Django模仿 SQL 束缚 ON DELETE CASCADE 的行为,并删除包含 ForeignKey的对象。当主表数据被删除时,从表对应的数据也被删除。
[*] Models.PROTECT:抛出 ProtectedError 以制止被引用对象的删除;等同于 mysql 默认的 RESTRICT。当主表数据被删除时,从表对应的数据不被删除。
[*] SET_NULL:设置 ForeignKey null;需要指定 null = True。当主表数据被删除时,从表对应的数据设置为null。
[*] SET_DEFAULT:将 ForeignKey 设置为其默认值,必须设置 ForeignKey 的默认值。当主表数据被删除时,从表对应的数据设置为相应的默认值。
创建模型类
[*]示例 - 创建模型类 – oto/models.py
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015223932082.png&pos_id=img-C7NdX2Dx-1735482065164
添加数据
[*]无外键的模型类:
[*]author1 = Author.objects.create(name=“王老师”)
[*]有外键的模型类:
[*]方式1:wife1 = Wife.objects.create(name=“王夫人”, author=author1) # 关联王老师对象
[*]方式2:wife1 = Wife.objects.create(name=“王夫人”, author_id=1) # 关联王老师对应的主键值
查询数据
正向查询
[*] 直接通过外键属性查询,则称为正向查询
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015225721620.png&pos_id=img-HWymvSUM-1735482065164
反向查询
没有外键属性的一方,可以调用反向属性查询关联的另一方
[*] 反向关联属性为:实例对象.引用类名(小写),如作家的反向引用为:作家对象.wife
[*] 当反向引用不存在时,则会触发异常
author1 = Author.objects.get(name=‘王老师’)
author1.wife.name
实验:一对一模型
[*] 创建应用:oto
(testenv) # python3 manage.py startapp oto
[*] 并在 settings.py 中将 oto 应用举行注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'music',
'news',
'sport',
'bookstore',
'oto',# 模型注册
]
[*] 修改 oto 应用下的 models.py,创建模型类
from django.db import models
class Author(models.Model):
# wife 反向属性:用作反向查询
name = models.CharField('姓名', max_length=11)
class Wife(models.Model):
name = models.CharField('姓名', max_length=11)
# 添加外键,指定关联的表
author = models.OneToOneField(Author, on_delete=models.CASCADE)
[*] 同步迁移数据库
(testenv) # python3 manage.py makemigrations
(testenv) # python3 manage.py migrate
[*] 进入 MySQL 环境,观察 wife 表中的外键,主动天生 author_id 外键
(testenv) # mysql -uroot -p123456
MariaDB [(none)]> USE mysite3;
MariaDB > DESC oto_author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name| varchar(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
MariaDB > DESC oto_wife;
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(11) | NO | | NULL | |
| author_id | int(11) | NO | UNI | NULL | | # 外键
+-----------+-------------+------+-----+---------+----------------+
[*] 测试:给两张表中添加数据,使用 Django Shell 的方式,两种方式添加数据
(testenv) # python3 manage.py shell
>>> from oto.models import *
>>> a1 = Author.objects.create(name="ben")
>>> a1.name
'ben'
>>> a1.id
1
>>> w1 = Wife.objects.create(name="benfuren", author=a1) # 方式一:指定对象赋值
>>> w1 = Wife.objects.create(name="benfuren", author_id=1)# 方式二:指定数据库字段(外键)赋值
>>> a2 = Author.objects.create(name="niu")
>>> a2.id# 查看作者id
2
>>> w2 = Wife.objects.create(name="niufuren", author_id=2)# 数据库字段赋值
[*] 查询:正向查询(带外键的表)
(testenv) # python3 manage.py shell
>>> from oto.models import *
>>> wife = Wife.objects.get(name="benfuren")
>>> wife.name
'benfuren'
>>> wife.author.name # 正向查询
'ben'
[*] 查询:反向查询(不带外键的表)
(testenv) # python3 manage.py shell
>>> from oto.models import *
>>> author1 = Author.objects.get(name="ben")
>>> author1.wife.name # 利用反向属性进行数据查询
'benfuren'
一对一映射关系总结
[*]一对一的模型类创建
[*]一对一的数据创建
[*]一对一的数据查询
[*]正向查询
[*]反向查询
一对多映射 models.ForeignKey()
概念与理解
[*]一对多是表示现实事物存在的一对多的对应关系
[*]如:一个学校有多个班级,一个班级有多个学生,一本书只能属于一个出版社,但是出版社可以出版多本书
[*]一对多需要明白出具体角色,在多表上设置外键
创建模型类
[*] 语法:当一个A类对象可以关联多个B类对象时
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015225827588.png&pos_id=img-ok1rCH6M-1735482065164
[*] ForeignKey必须指定 on_delete 模式
[*] 示例 – 创建模型类 - otm/models.py
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015225835740.png&pos_id=img-6AMqvdoE-1735482065164
添加数据
[*] 先创建“一”再创建多“多”
[*] 示例:
from .models import *
pub1=Publisher.objects.create(name='清华大学出版社')
Book.objects.create(title='C++', publisher=pub1)
Book.objects.create(title='Java', publisher_id=1)
查询数据
[*] 正向查询 [通过Book查询Publisher]
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231207978.png&pos_id=img-mfpPyuwm-1735482065164
[*] 反向查询 [通过Publisher查询对应的所有的Book] 需要用到 反向属性
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231215989.png&pos_id=img-TPUb6jga-1735482065165
实验:一对多模型
[*] 创建应用:otm
(testenv) # python3 manage.py startapp otm
[*] 并在 settings.py 中将 otm 应用举行注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'music',
'news',
'sport',
'bookstore',
'oto',
'otm',# 模型注册
]
[*] 修改 otm 应用下的 models.py,创建模型类
from django.db import models
class Publisher(models.Model):
#出版社[一]
name = models.CharField('出版社名称', max_length=50)
class Book(models.Model):
#书名 [多]
title = models.CharField('书名', max_length=11)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)# 外键
[*] 同步迁移数据库
(testenv) # python3 manage.py makemigrations
(testenv) # python3 manage.py migrate
[*] 进入 MySQL 环境,观察 Book 表中的外键
(testenv) # mysql -uroot -p123456
MariaDB [(none)]> USE mysite3;
MariaDB > DESC otm_publisher;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name| varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
MariaDB > DESC otm_book;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(11) | NO | | NULL | |
| publisher_id | int(11) | NO | MUL | NULL | | # 外键
+--------------+-------------+------+-----+---------+----------------+
MUL 允许多条数据有相同的publisher_id
[*] 测试:给两张表中添加数据,使用 Django Shell 的方式,先创建一,再创建多
(testenv) # python3 manage.py shell
>>> from otm.models import *
>>> p1 = Publisher.objects.create(name="中信出版社")
>>> p1
<Publisher: Publisher object (1)>
>>> p1.name
'中信出版社'
>>> p1.id
1
>>> b1 = Book.objects.create(title="python1", publisher=p1) # 类属性赋值
>>> b2 = Book.objects.create(title="python2", publisher_id=1)# 数据库字段赋值
>>> b1.publisher_id
1
>>> b2.publisher_id
1
MariaDB > select * from otm_book;
[*] 查询:正向查询
(testenv) # python3 manage.py shell
>>> from otm.models import *
>>> b1 = Book.objects.get(id=1)
>>> b1
<Book: Book object (1)>
>>> print(b1.title, b1.publisher.name)
python1 中信出版社
[*] 查询:反向查询
>>> from otm.models import *
>>> pub1 = Publisher.objects.get(name="中信出版社")
>>> pub1
<Publisher: Publisher object (1)>
>>> books = pub1.book_set.all()
>>> books
<QuerySet [<Book: Book object (1)>, <Book: Book object (2)>]>
>>> for book in books:
... print(book.title)
...
python1
python2
多对多映射 models.ManyToManyField()
概念与理解
[*]多对多表达对象之间多对多的复杂关系,如:每个都有差异的学校(小学,初中,高中……),每个学校都有差异的学生……
[*]Mysql 中创建多对多需要依赖第三张表来实现
[*]Django 中无需手动创建第三张表,这个操作Django主动完成
[*]语法:在关联的两个类中的任意一个类中,增加:
[*]属性 = models.ManyToManyField(MyModel)
创建模型类
用法示例:
[*] 一个作者可以出版多本图书
[*] 一本图书可以由多个作者共同编写
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231649187.png&pos_id=img-Z2bADj4c-1735482065165
[*] 用法示例—创建模型类:
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231706358.png&pos_id=img-A5Ikt1bM-1735482065166
添加数据
[*] 用法示例—创建数据
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231847122.png&pos_id=img-cMgEE34o-1735482065166
数据查询
**正向查询:**有多对多属性的对象查另一方
[*] 通过 Book 查询对应的所有的 Author
[*] 此时多对多属性相当于 objects
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231855563.png&pos_id=img-jD2s2Ly2-1735482065166
反向查询:
[*] 通过 Author查询对应的所有的 Book
[*] 使用反向属性 book_set
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015231900007.png&pos_id=img-9N4j9ujX-1735482065166
实验:多对多模型
[*] 创建应用:mtm
(testenv) # python3 manage.py startapp otm
[*] 并在 settings.py 中将 mtm 应用举行注册
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'music',
'news',
'sport',
'bookstore',
'oto',
'otm',
'mtm',# 模型注册
]
[*] 修改 mtm 应用下的 models.py,创建模型类
from django.db import models
class Author(models.Model):
name = models.CharField('姓名', max_length=11)
class Book(models.Model):
title = models.CharField('书名', max_length=11)
authors = models.ManyToManyField(Author)
[*] 同步迁移数据库
(testenv) # python3 manage.py makemigrations
(testenv) # python3 manage.py migrate
[*] 进入 MySQL 环境,观察 Django 帮助我们天生的中间表
(testenv) # mysql -uroot -p123456
MariaDB [(none)]> USE mysite3;
MariaDB > DESC mtm_author;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name| varchar(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
MariaDB > DESC mtm_book;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(11) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
MariaDB > DESC mtm_book_authors;# 中间表
+-----------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| book_id | int(11) | NO | MUL | NULL | |
| author_id | int(11) | NO | MUL | NULL | |
+-----------+---------+------+-----+---------+----------------+
[*] 测试:给两张表中添加数据,使用 Django Shell 的方式
(testenv) # python3 manage.py shell
>>> from mtm.models import *
# 两个人写了一本书
## 方案1:先创建 author,再关联 book
>>> author1 = Author.objects.create(name="teacher ben")
>>> author2 = Author.objects.create(name="teacher niu")
>>> book1 = author1.book_set.create(title="Python")
>>> author2.book_set.add(book1)
MariaDB > select * from mtm_book_authors;
## 方案2:先创建 book,再关联 author
>>> book2 = Book.objects.create(title="Django")
>>> author3 = book2.authors.create(name="teacher hu")
>>> book2.authors.add(author2)
# 一个人写了两本书
>>> book3 = Book.objects.create(title="HH")
>>> book4 = Book.objects.create(title="AA")
>>> author4 = book3.authors.create(name="teacher xie")
>>> book4.authors.add(author4)
[*] 查询:正向查询,通过 Book 查询对应的所有的 Author
(testenv) # python3 manage.py shell
>>> from mtm.models import *
>>> book1 = Book.objects.get(title="Django")
>>> book1.title
'Django'
>>> users = book1.authors.all()
>>> for user in users:
... print(user.name)
...
teacher niu
teacher hu
[*] 查询:反向查询
(testenv) # python3 manage.py shell
>>> from mtm.models import *
>>> author2 = Author.objects.get(name="teacher niu")
>>> books = author2.book_set.all()
>>> for book in books:
... print(book.title)
...
Python
Django
Cookies 和 Session
会话概念
[*]从打开浏览器访问一个网站,到关闭浏览器结束此次访问,称之为一次会话
[*]HTTP 协议是无状态的,导致会话状态难以保持
[*]试想一下,如果不保持会话状态,再电商网站购物的场景体验?
[*]Cookies和Session就是为了保持会话状态而诞生的两个存储技术
Cookies
Cookies 定义
cookies 是保存在客户端浏览器上的存储空间
Cookie 使用场景
在讲cookie前先了解下它的使用场景
[*] 使用Chrome浏览器打开京东网站且未登录情况下我的购物车未添加商品,以是商品数目是0
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233657587.png&pos_id=img-k8XHKApB-1735482065166
[*] 挑选3个商品加入购物车,此时购物车数目显示3
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233704125.png&pos_id=img-0QezeB4f-1735482065166
[*] 关闭 Chrome 浏览器再次打开京东首页发现购物车数目还是 3
[*] 如果此时换成 Firefox 浏览器打开京东首页发现购物车里的商品数目是 0
[*] 为什么 Chrome 浏览器未登录关闭浏览器后再次打开购物车商品数目没变,换个浏览器购物车商品数目就不是 3 了,这个场景就阐明白 2 点
[*]
[*]商品信息保存在当地了,未保存在浏览器缓存
[*]差异的浏览器cookie的保存路径不一样,并且各个浏览器的cookie信息互不影响
Cookies 特点
[*]cookie 在浏览器上是以键值对的形式举行存储的,键和值都是以 ASCII 字符串的形式存储(不能是中文字符串)
[*]存储的数据带有生命周期
[*]cookie 中的数据是按域存储隔离的,差异的域之间无法访问
[*]cookie 的内部的数据会在每次访问此网站时携带到服务器端,如果 cookie 过大会降低响应速度
Django 中的 cookie
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233715269.png&pos_id=img-8iCNwG81-1735482065166
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233722978.png&pos_id=img-cTWAOlCE-1735482065166
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233728676.png&pos_id=img-ngONL5wJ-1735482065166
实验:Cookies 操作
[*] 添加 cookies:修改 mysite3 下的 views.py 文件,添加指定视图函数
from django.shortcuts import render
from django.http import HttpResponse
def test_static(request):
return render(request, "test_static.html")
def set_cookies(request):# 添加测试cookie的函数
resp = HttpResponse('set cookies is ok')
resp.set_cookie('uuname', 'nfx' , 500)# cookie的key为'uuname',value为'nfx',过期时间500s
return resp
[*] 修改主路由 urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
......
path('set_cookies', views.set_cookies),
]
[*] 启动服务,测试 http://127.0.0.1:8000/set_cookies,观察网络请求中的 cookies 变革
网页返回
set cookies is ok
F12查看'网络',点击set_cookies,可以看到消息头中的响应头的Set-Cookies
查看'存储',Cookie中可以看到键值对 uuname: nfx
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233756487.png&pos_id=img-Uy2kcFAU-1735482065166
[*] 获取 cookies:修改 mysite3 下的 views.py 文件,添加指定视图函数
from django.shortcuts import render
from django.http import HttpResponse
def test_static(request):
return render(request, "test_static.html")
def set_cookies(request):
resp = HttpResponse('set cookies is ok')
resp.set_cookie('uuname', 'nfx',500)
return resp
def get_cookies(request):# 添加获取cookie的函数
value = request.COOKIES.get('uuname')
return HttpResponse(f'value is {value}')# 如果cookies过期了,则值为None
[*] 修改主路由 urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
# ......
path('set_cookies', views.set_cookies),
path('get_cookies', views.get_cookies),# 获取cookie的url
]
[*] 启动服务,测试 http://127.0.0.1:8000/get_cookies,观察网络请求中的 cookies 变革
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233820847.png&pos_id=img-Bhkoqx4Q-1735482065167
Session
Session概念
session 是在服务器上开辟了一段用于保存浏览器和服务器交互时的紧张数据
实现方式
[*]使用session需要在浏览器客户端启动 cookie,且在cookie中存储 sessionid
[*]每个客户端都可以在服务端有一个独立的 session
[*]注意:差异的请求者之间不会共享这个数据,与请求者逐一对应
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241016212617748.png&pos_id=img-ONAp79qg-1735482065167
在 Django 中的配置
[*]settings.py
向 INSTALLED_APPS 列表中添加
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233805615.png&pos_id=img-pJXhUUO6-1735482065167
向 MIDDLEWARE 列表中添加
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233828035.png&pos_id=img-wFFd9jln-1735482065167
session的使用
[*] session 对象是一个雷同与字典的 SessionStore 类型的对象,可以用类拟于字典的方式举行操作
[*] session 能够存储如字符串,整型,字典,列表等数据
[*] 保存 session 的值到服务器
[*]request.session[‘KEY’] = VALUE
[*] 获取 session 的值
[*]value = request.session[‘KEY’]
[*]value = request.session.get(‘KEY’, ‘默认值’)
[*] 删除 session
[*]del request.session[‘KEY’]
实验:Session 操作
[*] 添加以及获取 session:修改 mysite3 下的 views.py 文件,添加指定视图函数
def set_session(request):
request.session['uname'] = 'nfx'
return HttpResponse('set session is ok')
def get_session(request):
value = request.session['uname']
return HttpResponse(f'session value is {value}')
[*] 修改主路由 urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
......
path('set_cookies', views.set_cookies),
path('get_cookies', views.get_cookies),
path('set_session', views.set_session),# 设置session
path('get_session', views.get_session),# 获取session
]
[*] 启动服务:先测试 set 设置 session,然后再测试 get 获取 session
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233839450.png&pos_id=img-DRQq1l6n-1735482065167
select * from django_session;
执行 `del request.session['KEY']` 删除session,但只是让数据过期失效,实际上数据库里的数据没有被删除
django_session 表是单表设计;且该表数据量持续增加
- 可以定期执行 **python3 manage.py clearsessions**
- 该命令可删除已过期的 session 数据
settings.py 中相关配置项以及注意事项
[*] SESSION_COOKIE_AGE
[*]作用:指定sessionid在cookies中的保存时长 (默认2周),如下:
[*]比方:SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
[*] SESSION_EXPIRE_AT_BROWSER_CLOSE = True
[*]设置只要浏览器关闭时,session就失效(默认False)
[*] 注意:Django中的session数据存储在数据库中,以是使用session前需要确保已经执行过migrate操作将存储session表创建出来
[*] django_session 表是单表设计;且该表数据量连续增加
[*]可以定期执行 python3 manage.py clearsessions
[*]该下令可删除已逾期的 session 数据
Cookie和Session的对比
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=.%2Form03.assets%2Fimage-20241015233845836.png&pos_id=img-xKPZEw7E-1735482065167
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]