必备知识点 模型层ORM

模型层ORM

1.Django连接MySQL数据库

1.1 配置mysql参数

# MySQL配置项
DATABASES = {
    'default': {
        # ENGINE :默认的引擎 mysql
        'ENGINE': 'django.db.backends.mysql',
        # HOST : 主机地址127.0.0.1 / localhost
        "HOST": "47.100.88.80",
        # PORT : mysql 的服务端口
        "PORT": 3306,
        # USER : 用户名
        "USER": "root",
        # PASSWORD : 数据库密码
        "PASSWORD": "123456",
        # NAME  : 数据库名字
        "NAME":"django_02",
        # CHARSET : 默认编码集
        "CHARSET": "utf8mb4"
    }
}

1.2 启动Django报错

  • Did you install mysqlclient?

1.3 启动mysql报错

1.3.1 解决办法一
  • 猴子补丁
  • 可以放在任意位置的 __init__.py文件中
import pymysql

pymysql.install_as_MySQLdb()
1.3.2 下载第三方模块
  • 3.x版本以后建议你使用 mysqlclient
pip install mysqlclient
  • 运气
    • win 电脑给力一点,安装就不会报错
  • mac系统安装 mysqlclient 费劲
1.3.3 win报错解决办法
pip install mysqlclient-2.2.4-cp310-cp310-win_amd64.whl

2. Django中的orm框架

2.1 什么是ORM

  • ORM是一种将对象与关系型数据库之间的映射的技术,主要实现了以下三个方面的功能:
    • 数据库中的表映射为Python中的类
    • 数据库中的字段映射为Python中的属性
    • 数据库中的记录映射为Python中的实例
  • ORM的主要优点是可以减少开发人员编写重复的SQL语句的时间和工作量,并且可以减少由于SQL语句的调整和更改所带来的错误。

2.2 DjangoORM框架的优点

  • 与其他ORM框架相比,Django ORM拥有以下优点:
  • 简单易用:Django ORM的API非常简单,易于掌握和使用。
  • 丰富的API:Django ORM提供了丰富的API来完成常见的数据库操作,如增删改查等,同时也支持高级查询和聚合查询等操作。
  • 具有良好的扩展性:Django ORM可以与其他第三方库进行无缝集成,如Django REST framework、Django-Oscar等。
  • 自动映射:Django ORM支持自动映射,开发者只需要定义数据库表的结构,就可以自动生成相应的Python类,从而减少开发过程中的重复代码量。

2.3 ORM之建表操作

2.3.1 创建模型表
class User(models.Model):
    # 数据库中的字段映射未puthon的属性
    # 定义一个用户名,字符串类型,长度
    # mysql 字符串类型,varchar char
    # CharField字符串类型,max_length最大长度,verbose_name注释
    username = models.CharField(max_length=32, verbose_name="用户名")
    password = models.CharField(max_length=32, verbose_name="密码")
    # IntegerField相当于mysql的int字段
    age = models.IntegerField(verbose_name="年龄")
    # FloatField相当于mysql的float字段
    salary = models.FloatField(verbose_name="薪资")
2.3.2 迁移文件
  • 生成迁移文件
# 命令行
python manage.py makemigrations
chenxu@chenxudeMacBook-Pro new_djangoProject % python3.10 manage.py makemigrations

Migrations for 'app01':
  app01/migrations/0001_initial.py
    - Create model User
  • 迁移文件生效
# 迁移记录生效
python manage.py migrate

3. ORM操作

3.1 创建模型表

from django.db import models


# Create your models here.
class User(models.Model):
    name = models.CharField(max_length=32, verbose_name="姓名")
    age = models.IntegerField(verbose_name="年龄")

    # DateTimeField时间日期类型
    # auto_now_add 第一次注册数据的时候自动添加的时间和日期
    # auto_now 每一次更新数据的最后时间
    register_time = models.DateTimeField(auto_now_add=True, verbose_name="注册时间")
    update_time = models.DateTimeField(auto_now=True, verbose_name="更新时间")
  • 创建一对一表关系,
  • models.OneToOneField(to=UserInfo, on_delete=models.CASCADE)
class UserInfo(models.Model):
    name = models.CharField(max_length=32, verbose_name='姓名')
    # 一对多
    dp = models.ForeignKey(to=Depart, on_delete=models.CASCADE, verbose_name='标题id')

    class Meta:
        db_table = 'userinfo'


class Blog(models.Model):
  # 一对一
    user = models.OneToOneField(to=UserInfo, on_delete=models.CASCADE)
    blog = models.CharField(max_length=32, verbose_name='博客地址')
    desc = models.TextField(verbose_name='简介')

  • 一对多关系
  • models.ForeignKey(to=Depart, on_delete=models.CASCADE, verbose_name='标题id')
class Depart(models.Model):
    title = models.CharField(max_length=32, verbose_name='标题')

    class Meta:
        db_table = 'depart'

# 用户表
class UserInfo(models.Model):
    name = models.CharField(max_length=32, verbose_name='姓名')
    # 一对多
    dp = models.ForeignKey(to=Depart, on_delete=models.CASCADE, verbose_name='标题id')

    class Meta:
        db_table = 'userinfo'
  • 迁移数据库
python manage.py makemigrations
python manage.py migrate

3.2 操作模型层

import os

from django.test import TestCase

# Create your tests here.
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_project.settings')
    import django

    django.setup()
    from app01.models import User

    # 1.增加数据
    # user_obj = User.objects.create(name='serein', age=20)
    # print(user_obj)

    # 2.删除数据
    # 2.1.先查询直接删除
    # User.objects.filter(pk=1).delete()
    # 2.2 查询后在删除
    # user_obj = User.objects.filter(pk=3)
    # user_obj.delete()

    # 3.修改数据
    # 3.1 查询直接修改
    # User.objects.filter(pk=2).update(age=22)
    # 3.2 查询后在修改,用.属性修改,修改完必须对象.save保存,不然不生效
    # user_obj = User.objects.filter(pk=2).first()
    # user_obj.age = 30
    # user_obj.save()

    # 4.查询数据
    # 4.1 filter()方法,查询不到数据会返回null
    # .first()查询第一个
    # .last()最后一个
    # user_object = User.objects.filter(pk=2).first()
    # print(user_object)  # <QuerySet [<User: User object (2)>]>
    # 4.2 get()方法,查不到就报错
    # user_obj = User.objects.get(pk=2)
    # print(user_obj)  # User object (2)  查到的是user对象

    # 5.查询字段的值和键,查询当前表中所有的数据
    # 5.1 获取到的是字典类型的带键值的
    # user_data = User.objects.values()
    # print(user_data)
    # 5.2 values_list(),获得的是元祖,没有键,只有值
    # user_object1 = User.objects.filter(pk=2).values_list()
    # print(user_object1)

    # 6.对查询到的数据进行去重
    # user_obj = User.objects.values('age').distinct()
    # print(user_obj)  # <QuerySet [{'age': 30}, {'age': 40}, {'age': 28}]>

    # 7.排序
    # 排序对排序条件字段不加-号时代表从小到大,正序
    # user_object = User.objects.order_by('age').values()
    # print(user_object)
    # # 排序对排序条件字段加-号时代表从大到小,倒序
    # user_object = User.objects.order_by('-age').values()
    # print(user_object)

    # 8.统计个数
    # 直接统计表里的数据
    # user_obj = User.objects.count()
    # print(user_obj)
    # # 统计过滤条件筛选后的数据
    # user_obj = User.objects.filter(pk=2).count()
    # print(user_obj)

    # 9.剔除指定数据,相当于mysql中的不等于,
    # mysql中的SELECT * FROM User WHERE age != 40
    # user_obj = User.objects.exclude(age=40)
    # print(user_obj)

    # 10.校验数据是否存在
    user_exist = User.objects.filter(pk=1).exists()
    print(user_exist)
总结
    # (1) .create() : 创建数据
    # (2) .delete() : 删除数据
    # (3) .filter() : 查询指定数据,查不到不会报错,查出来是 queryset 对象
    # .filter().first()
    # .filter().last()
    # (3.1) .all() : 获取到当前表的所有数据对象 , queryset
    # (4) .get() : 查不到直接报错 ,查出来直接是用户 obj 对象
    # (5) .filter().update() : 修改数据(前提是查数据)
    # (6) .values() : 将所有的数据查出来,格式是字典
    # (7) .value_list() :  将所有的数据查出来,格式是元组
    # (8) .values().distinct() : 去重
    # (9) .order_by() : 按照指定字段排序 正序不加符号 ,倒序加 -
    # (9.1) .order_by().reverse()也可以排序
    # (10) .count() : 统计数据条数,可以统计整张表的数据量,也可以先过滤,统计过滤后的数据量
    # (11) .exclude() : 剔除符合条件的指定数据
    # (12) .filter().exist() : 判断当前数据是否存在

3.3 双下划线查询

# -*-coding: utf-8 -*-
# Project: orm_project
# @File : 02test__.py
# author : Serein
# Time: 2024-03-05 17:09
# IDE : PyCharm

import os
import random

from django.test import TestCase

# Create your tests here.
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_project.settings')
    import django

    django.setup()
    from app01 import models

    # 随机生成10条数据
    # for i in range(10):
    #     age = random.randint(20, 99)
    #     user_obj = User.objects.create(name=f"serein_{age}", age=age)

    # 1.条件运算
    # 1.1 大于28,__gt大于
    # user_obj = models.User.objects.filter(age__gt=28).values_list().count()
    # print(user_obj)  # 11
    # 1.2 小于28,__lt小于
    # user_obj = models.User.objects.filter(age__lt=28).values_list().count()
    # print(user_obj)  # 1
    # 1.3 大于等于28, __gte
    # user_obj = models.User.objects.filter(age__gte=28).values_list().count()
    # print(user_obj) # 12
    # 1.4 小于等于28,__lte
    # user_obj = models.User.objects.filter(age__lte=28).values_list().count()
    # print(user_obj)  # 2
    # 1.5 或条件,__in=(条件)
    # user_obj = models.User.objects.filter(age__in=(28, 35, 74, 98)).values()
    # print(user_obj)
    # 1.6 两个条件之间,__range=()
    # user_obj = models.User.objects.filter(age__range=(28, 98)).values().count()
    # print(user_obj)  # 11
    # 1.7 模糊查询,默认区分大小写 __contains=条件,只对字符串生效
    # user_obj = models.User.objects.filter(name__contains='_').values().count()
    # print(user_obj)
    # # 取消大小写限制 icontains
    # user_obj = models.User.objects.filter(name__icontains="S").count()
    # print(user_obj)
    # 1.8 以指定字符开头/结尾,__startswith,__endswith
    # user_obj = models.User.objects.filter(name__startswith="s").values()
    # print(user_obj)  # 11
    # user_obj = models.User.objects.filter(name__endswith="k").values()
    # print(user_obj)  # 1
    # 1.9 过滤指定时间区间
    # current_time = datetime.datetime.now()
    # user_obj = models.User.objects.filter(register_time__lt=current_time)
    # print(user_obj)

3.4 多表查询

3.4.1 创建表
from django.db import models


# 图书表
class Book(models.Model):
    # 书名
    title = models.CharField(max_length=32)
    # 书价格
    price = models.IntegerField()
    # 出版日期
    publish_date = models.DateTimeField()
    # 多对多的创建方式的第一种,直接创建一个ManyToManyField,指向需要关联的另一张表,django内部帮你自动完成第三张表的创建
    author = models.ManyToManyField('Author')
    publish = models.ForeignKey('Publish', on_delete=models.CASCADE)

    # 多对多的创建方式的第二种,半自动创建第三张表,通过参数关联,
    # author = models.ManyToManyField('Author', through='BookAuthor', through_fields=('book', 'author'))

    # 图书和作者:多对多,需要创建第三张表
    # 图书和作者,一本书可以背多个作者写,
    # 一个作者也可以写多本书

    # 图书和出版者之间,一对多
    # 一本书只能有一个出版社出版

# 多对多的创建方式的第三种,直接创建第三张表,建立外键关系(不推荐)
# class BookAuthor(models.Model):
#     book = models.ForeignKey('Book', on_delete=models.CASCADE)
#     author = models.ForeignKey('Author', on_delete=models.CASCADE)


# 出版社表
class Publish(models.Model):
    # 出版社名字
    name = models.CharField(max_length=32)
    # 出版社地址
    addr = models.CharField(max_length=255)
    # 出版社邮箱
    email = models.EmailField()


# 作者表
class Author(models.Model):
    # 作者姓名
    name = models.CharField(max_length=21)
    # 作者年龄
    age = models.IntegerField()

    # 作者和作者详情,一对一的关系
    # 创建外建字段`
    author_detail = models.ForeignKey('AuthorDetail', on_delete=models.CASCADE)


# 作者详细信息表
class AuthorDetail(models.Model):
    # 作者电话
    phone = models.CharField(max_length=11)
    # 作者地址
    addr = models.CharField(max_length=255)

3.4.2 多对多关系第三张表的创建方式
  • 全自动
class Book(models.Model):
    # 多对多的创建方式的第一种,直接创建一个ManyToManyField,指向需要关联的另一张表,django内部帮你自动完成第三张表的创建
    author = models.ManyToManyField('Author')
  • 半自动
class Book(models.Model):
    name = models.CharField(max_length=32)
    # 全自动
    # through_fields : 当前表是谁,第一个参数就是谁
    # 判断的本质:通过第三张表查询对应的表,需要用到哪个字段就把哪个字段放在前面
    authors = models.ManyToManyField(to='Author', through='BookAuthor', through_fields=('book', 'author'))


class Author(models.Model):
    name = models.CharField(max_length=32)


class BookAuthor(models.Model):
    book_id = models.ForeignKey(to='Book')
    author_id = models.ForeignKey(to='Author')
  • 手动,自己创建第三张表并创建外建
class BookAuthor(models.Model):
     book = models.ForeignKey('Book', on_delete=models.CASCADE)
     author = models.ForeignKey('Author', on_delete=models.CASCADE)

3.4.3 操作一对多和多对多关系
  • 多对多关系
# -*-coding: utf-8 -*-
# Project: orm_project
# @File : 多对多外建关系.py
# author : Serein
# Time: 2024-03-05 18:42
# IDE : PyCharm
import os
import random

from django.test import TestCase

# Create your tests here.
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_project.settings')
    import django

    django.setup()
    from app01 import models

    # 插入数据
    # 1.创建作者详情
    # detail_obj_serein = models.AuthorDetail.objects.create(phone="13023056160", addr='北京朝阳')
    # models.Author.objects.create(name='serein', age=18, author_detail=detail_obj_serein)
    # 2.创建作者
    # detail_obj_zzp = models.AuthorDetail.objects.create(phone="18712059833", addr='北京三平')
    # models.Author.objects.create(name='zzp', age=18, author_detail=detail_obj_zzp)
    #
    # # 3.创建出版社
    # models.Publish.objects.create(name='朝阳出版社', addr='北京朝阳', email='123@qq.com')
    # models.Publish.objects.create(name='上海出版社', addr='上海虹桥', email='456@qq.com')

    # 4.创建图书
    # models.Book.objects.create(title='西游记', price=999, publish_id=1)
    # models.Book.objects.create(title='水浒传', price=888, publish_id=1)
    # models.Book.objects.create(title='白蛇传', price=666, publish_id=2)
    #
    # 5. 图书关联作者和操作第三张表
    # (1)添加外键关系:在创建外建关系的表对象中获取到第三张表,利用add方法添加外键
    # 拿作者
    # author_obj = models.Author.objects.get(pk=1)
    # # 拿图书对象
    # book_obj = models.Book.objects.get(pk=1)
    # book_obj.author.add(author_obj)
    # (2) 删除外键关系,在创建外键关系的表对象中获得第三张表,利用remove方法删除外建关系
    # 获取到西游记,
    # author_obj = models.Author.objects.get(pk=1)
    # book_obj = models.Book.objects.get(pk=1)
    # book_obj.author.remove(author_obj)
    # (3) 修改多对多外建关系,在创建外建关系的表对象中获取到第三章表,利用set方法修改外建关系,set参数为列表
    # 按照上述先删除外建关系,在添加外建关系
    # author_obj_serein = models.Author.objects.get(pk=1)
    # author_obj_zzp = models.Author.objects.get(pk=2)
    # book_obj = models.Book.objects.get(pk=1)
    # # 自动删除外建关系然后自动关联外建关系
    # book_obj.author.set([author_obj_serein,author_obj_zzp])
    # (4) 清空第三张表的外建关系,在创建外建关系的表对象中获取到第三章表,利用clear清空表外建关系
    book_obj = models.Book.objects.get(pk=1)
    book_obj.author.clear()

  • 一对多的关系
   # 5.操作一对多关系
    # (1) 添加外建关系
    # 方式一:获取到对象在创建数据的时候指定publish=对象
    # 方式二: 创建数据时指定 publish_id = id
    # publish_obj = models.Publish.objects.get(pk=1)
    # book_obj = models.Book.objects.get(pk=1)
    # # 方式三: 先拿到对象,然后对象.属性=id
    # book_obj.publish_id = 2
    # # 需要sava保存,否则不生效
    # book_obj.save()
    # (2) 删除外建关系,过滤后直接删除
    # (3) 查询
    # book_obj = models.Book.objects.get(pk=1)
    # print(book_obj.publish.name)
    # (4) 改
    # 方式一: 先查询直接修改
    # models.Book.objects.filter(pk=1).update(publish_id=1)
    # 方式二:先拿到对象,然后对象.属性=id
    # book_obj = models.Book.objects.get(pk=1)
    # book_obj.publish_id = 2
    # book_obj.save()

3.5 正反向概念

# 正向:从有外间关系的这张表出发去被关联的那种表中插数据
# 图书表和出版社表:图书表出版社版表
# 图书.出版社.出版社名字
# 正向查询直接通过 .字段就能查到

# 反向: 从被关联的那种表中去有外间关系的那张表中查数据
# 图书表和出版社表:出版社表去查图书表
# 出版社表.图书表.图书名字 
# 反向查询需要按表名小写 ,__set 查询

3.6 正反向案例


import os
import random

from django.test import TestCase

# Create your tests here.
if __name__ == '__main__':
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_project.settings')
    import django

    django.setup()
    from app01 import models

    # (1)查询数据id为1的出版社,这是正向查找
    # book_obj = models.Book.objects.filter(pk=1).first()
    # book_obj = models.Book.objects.get(pk=1)
    # print(book_obj)
    # print(book_obj.publish.name) # 上海出版社

    # (2)查询数据逐渐id为2的作者
    # 通过第三张表.all可以获取所有关联的第三张表的数据
    # book_obj = models.Book.objects.get(pk=2)
    # print(book_obj)
    # print(book_obj.author.all())

    # (3)查询作者的电话号码
    # author_obj = models.Author.objects.get(pk=1)
    # print(author_obj)
    # print(author_obj.author_detail.phone) # 13023056160

    # 反向查询
    # (4)查询出版社为朝阳出版社出版的图书
    # 出版社去图书表里查询数据
    # publish_obj = models.Publish.objects.get(name="朝阳出版社")
    # print(publish_obj)
    # # 查询出版的图书
    # print(publish_obj.book_set.all())

    # (5)查询作者serein写过的书
    # 从作者表出发去图书表查询 --反向查询
    # author_obj = models.Author.objects.get(name='serein')
    # print(author_obj)
    # # 反向查图书
    # print(author_obj.book_set.all().values())

    # (6)查询电话号 13023056160 的作者姓名
    # 作者详情出发去作者表中查询数据
    # author_detail_obj = models.AuthorDetail.objects.get(phone='13023056160')
    # print(author_detail_obj.author_set.all().first())

    # 小结
    # 正向查询直接 .字段 直接查
    # 反向查询(反向就是有外间关系但是外间字段不在我这表表里,去有外间关系的那张表中查询数据就是反向查询)
    # 反向查询数据 没有外建的表明.有外建的表明_set.all() # 

3.7 跨表查询案例

【五】跨表查询案例
    # (1)查询serein的手机号和作者的姓名
    # values() 获取用户数据的键和值
    # [1]正向查询 : 从有外键字段的表出发去没有外键字段的表中查询
    # 先过滤筛选得到用户的queryset对象.values("没有外键字段的表名__表字段","自己有的字段名")
    # author_obj = models.Author.objects.filter(name="serein").values("author_detail__phone","name")
    # print(author_obj)
    # [2]反向查询 : 从没有外键字段的表向有外键字段的表查询
    # 先过滤出符合名字的用户对象数据.filter(有外键字段的表名__字段名=筛选值).values("有外键字段的表名__字段名","自己有的字段名")
    # author_obj = models.AuthorDetail.objects.filter(author__name="serein").values("author__name","phone")
    # print(author_obj)

    # (2)查询书籍ID为1的出版社名字和书的名字
    # 书籍表 --> 出版社查 : 正向
    # book_obj = models.Book.objects.filter(pk=1).values("publish__name","title")
    # print(book_obj) # <QuerySet [{'publish__name': '上海出版社', 'title': '西游记'}]>
    # 出版社  --> 图书查 : 反向
    # publish_obj = models.Publish.objects.filter(book__id=1).values("book__title","name")
    # print(publish_obj) # <QuerySet [{'book__title': '西游记', 'name': '上海出版社'}]>

    # (3)查询书籍ID为1的作者名字和作者电话
    # 书籍 ---> 作者表 : 正向
    # book_obj = models.Book.objects.filter(pk=1).values("author__name","author__author_detail__phone")
    # print(book_obj) # <QuerySet [{'author__name': 'serein', 'author__author_detail__phone': '15869699696'}]>
    # 作者 ---> 书籍 : 反向
    # author_obj = models.Author.objects.filter(book__id=1).values("book__title","name","author_detail__phone")
    # print(author_obj) # <QuerySet [{'book__title': '西游记', 'name': 'serein', 'author_detail__phone': '15869699696'}]>

3.8 聚合函数

# 【五】聚合函数
    # 【1】聚合函数的位置
    from django.db.models import Sum, Max, Min, Count, Avg
    # 使用聚合函数的前提是先分组再聚合 , Django提供了一个方法可以完成分组 aggregate
    # 【2】计算所有书的平均价格
    result_avg = models.Book.objects.aggregate(Avg("price"))
    print(result_avg) # {'price__avg': 851.0}
    result_sum = models.Book.objects.aggregate(Sum("price"))
    print(result_sum) # {'price__sum': 2553}

    # 【3】可以直接连着使用聚合函数
    res = models.Book.objects.aggregate(Avg('price'), Max('price'), Min('price'), Sum('price'), Count('pk'))
    print(res) # {'price__avg': 851.0, 'price__max': 999, 'price__min': 666, 'price__sum': 2553, 'pk__count': 3}

3.9 分组查询

# 【五】分组查询
    # 【1】MySQL中的分组查询 group_by ---> 严格模式
    # 【2】借助第三方模块
    # (1)统计一本书的作者的个数
    from django.db.models import Count, Min

    # book_author_num = models.Book.objects.annotate(author_number=Count("author")).values('title','author_number')
    # print(book_author_num) # <QuerySet [{'title': '西游记', 'author_number': 1}, {'title': '水浒传', 'author_number': 2}, {'title': '白蛇传', 'author_number': 0}]>
    # 如果不按照上面起别名,默认就是 字段名__聚合函数名
    # book_author_num = models.Book.objects.annotate(Count("author")).values()
    # print(book_author_num) #  <QuerySet [{'id': 1, 'title': '西游记', 'price': 999, 'publish_date': datetime.datetime(2024, 3, 5, 2, 28, 58, 607392, tzinfo=<UTC>), 'publish_id': 2, 'author__count': 1}

    # (2)统计价格最低的书
    # book_obj = models.Book.objects.annotate(Min("price")).values()
    # print(book_obj)
    # book_obj = models.Book.objects.annotate(book_min_price=Min("price")).values("title", "book_min_price")
    # print(book_obj)

    # (3)统计不止一个作者的书的名字
    book_obj = models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1).values()
    print(book_obj)

3.9 F查询与Q查询

   # F查询和Q查询,需导入第三方模块
   from django.db.models import F,Q
    # 【1】F查询
    # (1)卖出数量大于库存数量的数据
    # 获取指定字段的数据:卖出数,库存数
    # book_obj = models.Book.objects.filter(sale_num__gte=F('stock_num')).values()
    # print(book_obj)

    # (2)讲所有图书的价格提高100
    # book_obj = models.Book.objects.update(price=F('price') + 100)

    # (3)给你的书添加上爆款
    # book_obj= models.Book.objects.update(title = Concat(F("title"),Value('爆款')))

    # Q查询
    # (1)查询卖出数量大于80 库存数小于70 的数据
    # filter 可以放两个参数,但是两个参数不能是同一个字段

    # and的关系关系兼容二者
    # book_obj = models.Book.objects.filter(sale_num__gt=80,stock_num__lt=70).values()
    # book_obj = models.Book.objects.filter(Q(sale_num__gt=80),Q(stock_num__lt=70)).values()
    # print(book_obj)

    # or 表示and的关系
    # book_obj = models.Book.objects.filter(Q(sale_num__gt=80) | Q(stock_num__lt=70)).values()
    # print(book_obj)

    # |表示或的关系
    # book_obj = models.Book.objects.filter(Q(sale_num__gt=80) or Q(stock_num__lt=70)).values()
    # print(book_obj)


4. django开启事务

    # django 开始事务
    from django.db import transaction

try:
    # 开启事务
    with transaction.atomic():
        # 在事务开始前创建保存点
        save_id = transaction.savepoint()
        # 这部分代码会在事务中执行
        ...
        transaction.savepoint_commit(save_id)

except Exception as e:
    transaction.savepoint_rollback(save_id)

5. choices参数

# 创建作者表
class Author(models.Model):
    gender_choice = (
        (0, "male"),
        (1, "female"),
        (2, "other"),
    )
    # 作者名字
    name = models.CharField(max_length=32)
    # 作者年龄
    age = models.IntegerField()
    # 0 女 1 男 2 保密
    gender = models.IntegerField(choices=gender_choice, default=2)

    # 作者和作者详情:一对一
    # 创建外键字段
    author_detail = models.ForeignKey("AuthorDetail", on_delete=models.CASCADE)

    class Meta():
        # 默认表名是 app01_book
        # book
        db_table = "Author"
        verbose_name_plural = "作者表"
        


author_obj = models.Author.object.filter(pk=1).values()
author_obj = models.Author.object.get(pk=1)

# 拿到的是数字
print(author_obj.gender)
# gender.choice,拿到的是所有数据的备选项
print(author_obj.gender_choice)
# 获取到数字对应的文字
print(author_obj.get_gender_display())
posted @ 2024-03-28 19:55  Formerly0^0  阅读(3)  评论(0编辑  收藏  举报