Django基础四

目录

  • 聚合查询
    • 级联更新 级联删除
    • 聚合函数
      • 1、关键字 aggregate
    • 分组查询: group by
      • 1、关键字 annotate
    • F 查询
    • Q 查询
  • Django ORM中常用字段和参数
    • 说明:
      • 常用字段
      • 字段合集
  • 事物( transaction)
    • 概念:
    • 事物的四大特性:
      • 原子性 atomicity
      • 一致性 consistency
      • 隔离性 Isolation
      • 持久性 durability
    • 数据库三大范式
      • 第一范式(1NF)
      • 第二范式(2NF)
      • 第三范式(3NF)
    • rollback()回滚
    • Django中如何开启事务:

聚合查询

级联更新 级联删除

操作外键字段管理数据的时候,出版社跟书是一对多关系 外键字段在书表中。这个时候如果把出版社删了 所对应的书也会被自动删除。这个时候如果把出版社主键值改变了 那么书籍表中对应的出版社主键值也会自动修。

聚合函数

​ 聚合函数必须用在分组之后,没有分组其实默认整体就是一组

​ Max, Min, Sum, Avg, Count

1、关键字 aggregate

​ 2、还需要导入模块

​ from django.db.models import Max, Min, Sum, Avg, Count

​ 只要跟数据库相关的功能,基本上都在django.db.models里边,如果没有,去django.db里边找找看。

​ 1、筛选出价格最高的书籍

res = models.Book.objects.aggregate(mr = Max('price'))
print(res)

​ 2、求书籍总价格

res = models.Book.objects.aggregate(sm=Sum('price'))
print(res)

​ 3、求书籍的平均价格

res = models.Book.objects.aggregate(av=Avg('price'))
price(res)

​ 4、一起使用

res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Avg('price'))
print(res)

分组查询: group by

应用场景:统计平均值、计算比例

1、关键字 annotate

2、借助于聚合函数

​ from django.db.models import Max, Min, Sum, Avg, Count

django中models后点什么,就按照什么分组

题目中‘每’后是什么,就按什么分组(如“统计每个部门的人数”,则按部门分组)

​ 1、统计每本书的作者个数、书名、作者人数

res = models.Book.objects.annotate(author_num=Count('authors__id')).values('title','author_num')    

print(res)

​ 2、统计出每个出版社卖得最便宜得书得价格

res = models.Publish.objects.annotate(mi n_price=Min('book__price')).values('name', 'min_price')
print(res)

3、统计不止一个作者的书

先拿书及对应的作者数

再筛选出大于1的

res = models.Book.objects.annotate(author_num=Count('author')).filter(author_num__gt=1).values('title','author_num')
print(res)

4、查询各个作者出的书的总价格

res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
print(res)

F 查询

F 能获取表中字段对应的值

先导入F模块

from django.db.models import F

1、查询库存数大于卖出数的书籍

res = models.Book.objects.filter(ku_cun__gt=F('mai_chu'))
print(res)

2、将所有书的价格上涨100块

models.Book.objects.all().update(price=F('price')+100)

3、给所有书名添加统一后缀。操作字符串需要借助于Concat

先导入两个模块

from django.db.models.functions import Concat
from django.db.models import Value

res = models.Book.objects.update(name=Concat(F('name'),Value('新款')))

Q 查询

Q 能获取表中字段对应的值

先导入Q模块

from django.db.models import Q

1、查询书名是三国演义 或者库存数是500的书籍

res = models.Book.objects.filter(title='三国演义',kun_cun=500)  # 用逗号是and关系
res = models.Book.objects.filter(Q(title='三国演义')|Q(ku_cun=500))  # 用|是or关系
print(res)

Q对象的高级用法

q = Q()
q.connector = 'or'
q.children.append('title','三国演义')
q.children.append('ku_cun__gt',500)
res = models.Book.objects.filter(q)
print(res)

Django ORM中常用字段和参数

说明:

1、表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时。

2、id字段是自动添加的,如果你想要指定自定义主键,只需在其中一个字段中指定 primary_key=True 即可。如果Django发现你已经明确地设置了Field.primary_key,它将不会添加自动ID列。

3、本示例中的CREATE TABLE SQL使用PostgreSQL语法进行格式化,但值得注意的是,Django会根据配置文件中指定的数据库后端类型来生成相应的SQL语句。

常用字段

Autofield

int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

IntegerField 对应int

整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)

BigIntegerField 对应bigint

CharField 对应varchar

字符类型,必须提供max_length参数, max_length表示字符长度。

DateField

日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

DateTimeField

日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

​ auto_now:每次修改数据的时候 都会自动将当前修改时间更新上去 实时更新
​ auto_now_add:在创建数据的时候 会将当前时间自动记录 之后不会更新修改时间,可手动修改

EmaiField

BooleanField 传值True或False,一般存为1或0

TextField 用来存大段文本

FileField

专门用来文件路径 '/etc/data/a.txt'
upload_to = '/etc/data'
给该字段传值的时候 直接传文件对象
会自动将文件对象保存到upload_to后面指定的文件路径中
然后将路径保存到数据库

DecimalField

10进制小数,需要传两个参数:
max_digits,小数总长度
decimal_places,小数位长度

自定有char字段

class MyCharField(models.Field):
    def __init__(self,max_length,*args,**kwargs):
        self.max_length = max_length
        # 重新调用父类的方法
        super().__init__(max_length=max_length,*args,**kwargs)
            
        def db_type(self, connection):
        return 'char(%s)'%self.max_length

字段合集

AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 0 ~ 32767
    IntegerField(Field)
        - 整数列(有符号的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型

 字段合集

事物( transaction)

概念:

事务是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

事物的四大特性:

原子性 atomicity

原子性是指事物的全部操作在数据库中是一个不可分割的任务单位,要么全都完成,要么全都不执行

一致性 consistency

一致性是指在事物执行前和执行后,数据库都处于一个一致性状态。事物操作使数据库由一个一致性状态变化为另一个一致性状态。

隔离性 Isolation

隔离性是指事物与事物间相互隔离,互不干扰。如果事物T1与T2都要操作同一数据对象,那么T2要么在T1执行之前就结束,要么在T1执行完毕才开始。二者不能同时进行。

持久性 durability

事物的持久性是指,事物对数据库的作用是永久性的,即使数据库系统发生故障也不会对这个作用产生任何影响。

数据库三大范式

第一范式(1NF)

简单说就是:数据库表中每个字段都不可拆分,具有原子性。能拆分的必须拆分到不可拆分为止。

例如人员信息表中某人填了两个电话号码,那么应该将其分开填入两个字段,电话1,电话2

第二范式(2NF)

1、每个字段都不可拆分(满足第一范式要求)

2、表中字段没有部分依赖

例如信息表:学号, 姓名, 年龄, 课程名称, 成绩, 学分;

这个表明显表示两组信息:学生信息, 课程信息,不符合第二范式。

存在问题:数据冗余,每条记录都含有相同信息。

解决:分成学生表和课程表分别存储即可。

第三范式(3NF)

1、每个字段都不可拆分(满足第一范式要求)

2、表中字段没有部分依赖

3、没有传递依赖(例如:部门信息表)

例如信息表:学号, 姓名, 年龄, 所在学院, 学院联系电话,

存在传递依赖(学号) → (所在学院) → (学院地点, 学院电话)

解决:分成学生表,学院表即可。

rollback()回滚

当一个事件执行了一部分之后就中断,未执行的部分不能接着正常执行时,已执行的部分就会被撤销,数据库回到执行前的状态,这个撤回动作就叫做回滚。

Django中如何开启事务:

    from django.db import transaction
  
    with transaction.atomic():
        # 在缩进的代码中书写数据库操作
        # 该缩进内的所有代码 都是一个事务
        pass

你可能感兴趣的:(Django基础四)