orm03

news2025/1/3 5:49:16

admin后台管理

什么是admin后台管理

django提供了比较完善的后台数据库的接口,可供开发过程中调用和测试使用

django会搜集所有已注册的模型类,为这些模型类提供数据管理界面,供开发使用

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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) [root@localhost mysite3]# 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/N]: y  # 如果密码短需要手动确定
    Superuser created successfully.
    
  • 启动服务 django 服务

    (testenv) [root@localhost mysite3]# python3 manage.py runserver
    
  • 后台管理的登录地址:http://127.0.0.1:8000/admin

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注册自定义模型类

  • 若要自己定义的模型类也能在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)方法解决显示问题,如:

      外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验:注册模型类

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 修改 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 后台管理系统,观察界面

  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 点击Books链接,查看图书详情页

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 这里显示的内容是 __str__ 方法封装的字符串,所以可以自定义修改显示的字段

  •     def __str __ (self):
            return f'书名:{self.title},价格:{self.price},出版社:{self.pub},零售价:{self.market_price}'
    
    
  • 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

模型管理器类

理解与说明

作用:为后台管理界面添加便于操作的新功能

说明:后台管理器类须继承自 Django.contrib.admin 里的 ModelAdmin

使用方法
  • 在 <应用app>/admin.py 里定义模型管理器类

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 绑定注册模型管理器和模型类

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 案例

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

类属性说明
  • **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进入详情页,发现修改内容均已在管理界面生效

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

默认自带按字段排序功能

Meta类

在管理页面看见的模型类的名称,可以通过Meta内嵌类来修改。

通过Meta内嵌类定义模型类的属性,用法如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验:修改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类对模型类的属性修改

用户管理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 权限

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

关系映射

什么是关系映射

在关系型数据库中,通常不会把所有数据都放在同一张表中,不易于扩展,常见关系映射有:

  • 一对一映射
    • 如:一个身份证对应一个人
  • 一对多映射
    • 如:一个班级可以有多个学生
  • 多对多映射
    • 如:一个学生可以报多个课程,一个课程可以有多个学生学习

一对一映射 models.OneToOneField()

概念与理解
  • 一对一是表示现实事物间存在的一对一的对应关系

  • 如:一个家庭只有一个户主,一个男人有一个妻子,一个人有一个唯一的指纹信息等

  • 语法:OneToOneField(类名, on_delete=xxx)

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

特殊字段选项【必须】
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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加数据
  • 无外键的模型类[Author]:
    • author1 = Author.objects.create(name=“王老师”)
  • 有外键的模型类[Wife]:
    • 方式1:wife1 = Wife.objects.create(name=“王夫人”, author=author1) # 关联王老师对象
    • 方式2:wife1 = Wife.objects.create(name=“王夫人”, author_id=1) # 关联王老师对应的主键值
查询数据
正向查询
  • 直接通过外键属性查询,则称为正向查询

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

反向查询

没有外键属性的一方,可以调用反向属性查询关联的另一方

  • 反向关联属性为:实例对象.引用类名(小写),如作家的反向引用为:作家对象.wife

  • 当反向引用不存在时,则会触发异常

    author1 = Author.objects.get(name=‘王老师’)
    author1.wife.name
    
实验:一对一模型
  • 创建应用:oto

    (testenv) [root@localhost mysite3]# 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) [root@localhost mysite3]# python3 manage.py makemigrations
    (testenv) [root@localhost mysite3]# python3 manage.py migrate
    
  • 进入 MySQL 环境,观察 wife 表中的外键,自动生成 author_id 外键

    (testenv) [root@localhost mysite3]# mysql -uroot -p123456
    MariaDB [(none)]> USE mysite3;
    MariaDB [mysite3]> DESC oto_author;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(11) | NO   |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    
    
    MariaDB [mysite3]> 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) [root@localhost mysite3]# 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) [root@localhost mysite3]# python3 manage.py shell
    >>> from oto.models import *
    >>> wife = Wife.objects.get(name="benfuren")
    >>> wife.name
    'benfuren'
    >>> wife.author.name       # 正向查询
    'ben'
    
  • 查询:反向查询(不带外键的表)

    (testenv) [root@localhost mysite3]# python3 manage.py shell
    >>> from oto.models import *
    >>> author1 = Author.objects.get(name="ben")
    >>> author1.wife.name       # 利用反向属性进行数据查询
    'benfuren'
    
一对一映射关系总结
  • 一对一的模型类创建
  • 一对一的数据创建
  • 一对一的数据查询
    • 正向查询
    • 反向查询

一对多映射 models.ForeignKey()

概念与理解
  • 一对多是表示现实事物存在的一对多的对应关系
  • 如:一个学校有多个班级,一个班级有多个学生,一本书只能属于一个出版社,但是出版社可以出版多本书
  • 一对多需要明确出具体角色,在多表上设置外键
创建模型类
  • 语法:当一个A类对象可以关联多个B类对象时

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • ForeignKey必须指定 on_delete 模式

  • 示例 – 创建模型类 - otm/models.py

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加数据
  • 先创建“一”再创建多“多”

  • 示例:

    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]

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 反向查询 [通过Publisher查询对应的所有的Book] 需要用到 反向属性

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验:一对多模型
  • 创建应用:otm

    (testenv) [root@localhost mysite3]# 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) [root@localhost mysite3]# python3 manage.py makemigrations
    (testenv) [root@localhost mysite3]# python3 manage.py migrate
    
  • 进入 MySQL 环境,观察 Book 表中的外键

    (testenv) [root@localhost mysite3]# mysql -uroot -p123456
    MariaDB [(none)]> USE mysite3;
    
    
    MariaDB [mysite3]> DESC otm_publisher;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(50) | NO   |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    
    MariaDB [mysite3]> 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) [root@localhost mysite3]# 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 [mysite3]> select * from otm_book;
    
  • 查询:正向查询

    (testenv) [root@localhost mysite3]# 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)
创建模型类

用法示例:

  • 一个作者可以出版多本图书

  • 一本图书可以由多个作者共同编写

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 用法示例—创建模型类:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加数据
  • 用法示例—创建数据

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据查询

**正向查询:**有多对多属性的对象查另一方

  • 通过 Book 查询对应的所有的 Author

  • 此时多对多属性相当于 objects

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

反向查询:

  • 通过 Author查询对应的所有的 Book

  • 利用反向属性 book_set

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验:多对多模型
  • 创建应用:mtm

    (testenv) [root@localhost mysite3]# 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) [root@localhost mysite3]# python3 manage.py makemigrations
    (testenv) [root@localhost mysite3]# python3 manage.py migrate
    
  • 进入 MySQL 环境,观察 Django 帮助我们生成的中间表

    (testenv) [root@localhost mysite3]# mysql -uroot -p123456
    MariaDB [(none)]> USE mysite3;
    
    MariaDB [mysite3]> DESC mtm_author;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | name  | varchar(11) | NO   |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    
    
    MariaDB [mysite3]> DESC mtm_book;
    +-------+-------------+------+-----+---------+----------------+
    | Field | Type        | Null | Key | Default | Extra          |
    +-------+-------------+------+-----+---------+----------------+
    | id    | int(11)     | NO   | PRI | NULL    | auto_increment |
    | title | varchar(11) | NO   |     | NULL    |                |
    +-------+-------------+------+-----+---------+----------------+
    
    
    MariaDB [mysite3]> 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) [root@localhost mysite3]# 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 [mysite3]> 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) [root@localhost mysite3]# 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) [root@localhost mysite3]# 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

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 挑选3个商品加入购物车,此时购物车数量显示3

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 关闭 Chrome 浏览器再次打开京东首页发现购物车数量还是 3

  • 如果此时换成 Firefox 浏览器打开京东首页发现购物车里的商品数量是 0

  • 为什么 Chrome 浏览器未登录关闭浏览器后再次打开购物车商品数量没变,换个浏览器购物车商品数量就不是 3 了,这个场景就说明了 2 点

    • 商品信息保留在本地了,未保留在浏览器缓存
    • 不同的浏览器cookie的保留路径不一样,并且各个浏览器的cookie信息互不影响
Cookies 特点
  • cookie 在浏览器上是以键值对的形式进行存储的,键和值都是以 ASCII 字符串的形式存储(不能是中文字符串)
  • 存储的数据带有生命周期
  • cookie 中的数据是按域存储隔离的,不同的域之间无法访问
  • cookie 的内部的数据会在每次访问此网站时携带到服务器端,如果 cookie 过大会降低响应速度
Django 中的 cookie

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

实验: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
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 获取 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 变化

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Session

Session概念

session 是在服务器上开辟了一段用于保留浏览器和服务器交互时的重要数据

实现方式
  • 使用session需要在浏览器客户端启动 cookie,且在cookie中存储 sessionid
  • 每个客户端都可以在服务端有一个独立的 session
  • 注意:不同的请求者之间不会共享这个数据,与请求者一一对应

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 Django 中的配置
  • settings.py

向 INSTALLED_APPS 列表中添加

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

向 MIDDLEWARE 列表中添加

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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的对比

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2267848.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE5材质节点Panner

Panner节点可以让贴图动起来&#xff0c;快捷键是P&#xff0c;Speed的数值大小就是贴图移动的快慢&#xff0c;x和y是方向 这个节点可以用来做&#xff0c;传送带&#xff0c;护盾&#xff0c;河流&#xff0c;岩浆&#xff0c;瀑布等 制作岩浆流动效果 创建材质&#xff0c;…

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo

【论文阅读笔记】Scalable, Detailed and Mask-Free Universal Photometric Stereo 前言摘要引言Task 相关工作方法SDM-UniPS预处理尺度不变的空间光特征编码器像素采样变压器的非局部交互 PS-Mix数据集 实验结果训练细节评估和时间&#xff1a; 消融实验定向照明下的评估没有对…

道路倒角 三角网 两侧偏移

public void 多段线和直线两侧缓冲区(){List<Curve> ents1 Z.db.SelectEntities<Curve>();List<Polyline> ents Z.db.CurvesToPolyLines2(ents1);//Z.db.SelectEntities<Polyline>();double offsetDistance 5.0;//p距离double offsetDistance2 1.0…

贪心算法(常见贪心模型)

常见贪心模型 简单排序模型 最小化战斗力差距 题目分析&#xff1a; #include <bits/stdc.h> using namespace std;const int N 1e5 10;int n; int a[N];int main() {// 请在此输入您的代码cin >> n;for (int i 1;i < n;i) cin >> a[i];sort(a1,a1n);…

供应链系统设计-供应链中台系统设计(六)- 商品中心概念篇

概述 我们在供应链系统设计-中台系统设计系列&#xff08;五&#xff09;- 供应链中台实践概述 中描述了什么是供应链中台&#xff0c;供应链中台主要包含了那些组成部门。包括业务中台、通用中台等概念。为了后续方便大家对于中台有更深入的理解&#xff0c;我会逐一针对中台…

Linux(Centos 7.6)目录结构详解

Linux(Centos 7.6)是一个操作系统&#xff0c;其核心设计理念是将一切资源抽象为文件&#xff0c;即一切皆文件。比如系统中的硬件设备硬盘、网络接口等都被视为文件。Windows系统一般是分为C、D、E盘。而Linux(Centos 7.6)是以斜线"/"作为文件系统的开始目录&#x…

transform、animation、transition?

transform、transition 和 animation 都是 CSS 属性&#xff0c;用于创建视觉效果&#xff0c;但它们的工作方式和用途不同&#xff1a; 1. transform (变换元素): 作用: transform 用于改变元素的旋转、缩放、移动、倾斜等属性&#xff0c;但不改变元素的初始状态和最终状态…

大数据技术-Hadoop(三)Mapreduce的介绍与使用

目录 一、概念和定义 二、WordCount案例 1、WordCountMapper 2、WordCountReducer 3、WordCountDriver 三、序列化 1、为什么序列化 2、为什么不用Java的序列化 3、Hadoop序列化特点&#xff1a; 4、自定义bean对象实现序列化接口&#xff08;Writable&#xff09; 4…

Echarts+vue电商平台数据可视化——webSocket改造项目

websocket的基本使用&#xff0c;用于测试前端能否正常获取到后台数据 后台代码编写&#xff1a; const path require("path"); const fileUtils require("../utils/file_utils"); const WebSocket require("ws"); // 创建WebSocket服务端的…

神经网络-Inception

Inception网络是由Google开发的一种深度卷积神经网络架构&#xff0c;旨在解决计算机视觉领域中的图像分类和物体识别任务。 Inception网络最初在2014年被提出&#xff0c;并在ImageNet图像分类挑战赛上取得了很好的结果。其设计灵感来自于模块化的思想&#xff0c;将不同尺度…

js给dom分页

减少js操作dom js引擎与渲染引擎相互独立, js操作dom过程开销大操作到了dom层面会触发渲染树的变化,触发回流与重绘开销大 让js给dom分压 js处理完操作后,最后给dom 缓存变量 let container document.getElementById(container) let content for(let count0;count<…

深度学习——神经网络中前向传播、反向传播与梯度计算原理

一、前向传播 1.1 概念 神经网络的前向传播&#xff08;Forward Propagation&#xff09;就像是一个数据处理的流水线。从输入层开始&#xff0c;按照网络的层次结构&#xff0c;每一层的神经元接收上一层神经元的输出作为自己的输入&#xff0c;经过线性变换&#xff08;加权…

秒鲨后端之MyBatis【2】默认的类型别名、MyBatis的增删改查、idea中设置文件的配置模板、MyBatis获取参数值的两种方式、特殊SQL的执行

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01;! ! ! 下篇更新&#xff1a; 秒鲨后端之MyBatis【3】自定义映射resultMap、动态SQL、MyBatis的缓存、MyBatis的逆向工程、分页插件。 默认的类型别名 MyBatis的增删改查 添加 <!--int insertUs…

瑞芯微全新芯片平台RK3506优势详解,高集成低功耗,为工业而生 触觉智能测评

RK3506是瑞芯微Rockchip在2024年第四季度全新推出的Arm嵌入式芯片平台&#xff0c;三核Cortex-A7单核Cortex-M0多核异构设计&#xff0c;CPU频率达1.5Ghz, M0 MCU为200Mhz。 而RK3506芯片平台下的工业级芯片型号RK3506J&#xff0c;具备-40-85℃的工业宽温性能、发热量小&#…

AIOps平台的功能对比:如何选择适合的解决方案?

定义与概念 AIOps&#xff0c;即人工智能运维&#xff08;Artificial Intelligence for IT Operations&#xff09;&#xff0c;是将人工智能技术应用于 IT 运维领域&#xff0c;以实现自动化、智能化的运维管理。它通过整合大数据、机器学习等先进技术&#xff0c;对海量运维数…

Python + 深度学习从 0 到 1(03 / 99)

希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持&#xff01; ⭐ 神经网络的数据表示 – 张量 你可能对矩阵很熟悉&a…

Lumos学习王佩丰Excel第二十三讲:饼图美化与PPT图表

一、双坐标柱形图的补充知识 1、主次坐标设置 2、主次坐标柱形避让&#xff08;通过增加两个系列&#xff0c;挤压使得两个柱形挨在一起&#xff09; 增加两个系列 将一个系列设置成主坐标轴&#xff0c;另一个设成次坐标轴 调整系列位置 二、饼图美化 1、饼图美化常见设置 …

基于Vue+SSM+SpringCloudAlibaba书籍管理系统

功能要求 一、登录功能&#xff08;http://localhost:8080/#/login&#xff09; 输入账号和密码(admin/admin)进行登录&#xff1a; 如果密码错误&#xff0c;给出提示信息 如果密码正确&#xff0c;跳转到主页 账号或密码错误&#xff1a; 账号密码正确&#xff1a;跳转到…

【优先算法】滑动窗口 --(结合例题讲解解题思路)(C++)

目录 ​编辑 1.什么是滑动窗口&#xff1f; 2. 滑动窗口例题 2.1 例题1&#xff1a;长度最小的子数组 2.1.1 解题思路 2.1.2 方法一&#xff1a;暴力枚举出所有的子数组的和 2.1.3 方法二&#xff1a;使用 “同向双指针” 也就是滑动窗口来进行优化 2.2 例题2&#xff1a;无重…

VS Code 从命令行启动

在 VS Code 中&#xff0c;code 命令允许你在命令行中快速打开文件、文件夹或新窗口。 安装 原本地址&#xff1a;https://code.visualstudio.com/docs/setup/mac 使用 使用 code 命令 打开文件&#xff1a;你可以通过在命令行输入 code 文件名 来直接打开一个文件。 打开文…