码迷,mamicode.com
首页 > 其他好文 > 详细

肆拾捌 --- 模型层下

时间:2019-10-27 18:25:29      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:状态   商品   隔离   自定义   auth   ext   ice   nosql数据库   product   

django模板层下

一、聚合查询与分组查询

1.1 聚合

? 聚合函数是sql的基本函数,会对一组值执行计算并返回单一的值。

from django.db.models import Avg,Sun,Max,Min,Count

res1 = models.Book.objects.all().aggregate(Avg('price'))
res2 = models.Book.objects.all().aggregate(Max('price'))
res3 = models.Book.objects.all().aggregate(Min('price'))
res4 = models.Book.objects.all().aggregate(Sum('price'))
res5 = models.Book.objects.all().aggregate(Count('title'))
res6 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title'))

1.2 分组

? 分组查询使用关键字annotate()方法。

? 1.统计每一本书的作者个数:

res = models.Book.objects.annotate(author_num = Count('author')).values('author_num')

? 2.统计每个出版社卖的价格做便宜的书的价格:

res = models.Publish.objects.annotate(price_min=min(;book__price)).values('price_min')

? 3.统计不止一个作者的图书:

res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num')

? 4.查询每个作者出的图书的总价:

res = models.Author.object.annotate(sun_price=Sum('book__price')).values('sum_price')

二、F与Q查询:

2.1 F查询

? jango提供的F()方法可以在查询中引用字段,比较来自同一个model中的两个不同字段的值。

from django.db.models import F

? 1.查询出卖出数大于库存数的商品:

res = models.Product.objects.filter(maichu__gt=F('kucun'))

? F可以取到表中某个字段对应的值来当作筛选条件,而不是自定义常量的条件了,实现了动态比较的效果。

? Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。基于此可以对表中的数值类型进行数学运算。

? 将每个商品的价格提高50块:

res = models.Product.object.update(price=F('price')+50)

2.2 Q查询

? filter() 等方法中逗号隔开的条件是与的关系。 如果需要执行更复杂的查询(例如OR语句),可以使用Q对象

from django.db.models import Q

? 1.查询 卖出数大于100 或者 价格小于100块的:

res = models.Prodect.object.filter(Q(maichu__gt=100)|Q(price__lt=100))

? 2.查询 库存数是100 并且 卖出数不是0 的产品:

res = models.Prodect.objects.filter(Q(kucun=100)&~Q(maichu=0))

三、orm中的字段

3.1 常见字段

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)
        - 二进制类型

 字段合集

3.2 字段参数

null
    -用于表示某个字段可以为空。
unique
    -如果设置为unique=True 则该字段在此表中必须是唯一的 。

db_index
    -如果db_index=True 则代表着为此字段设置索引。

default
    -为该字段设置默认值。
    
auto_now_add
    -配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

auto_now
    -配置上auto_now=True,每次更新数据记录的时候会更新该字段。
    
to
设置要关联的表

to_field
设置要关联的表的字段

on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。

models.CASCADE

删除关联数据,与之关联也删除

db_constraint
是否在数据库中创建外键约束,默认为True。

四、查询与优化

4.1 only与defer

? only:

res = models.Book.object.all()
for i in res:
    print(r.title)

? only会将括号内的字段对应的值,直接封装到返回给你的对象中点该字段,不需要再走数据库一旦你点了不是括号内的字段 ,就会频繁的去走数据库查询。

? defer:

res = models.Book.objects.defer('title')  # defer和only互为反关系
for r in res:
    print(r.title)

? defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段,不需要再走数据库一旦你点了括号内的字段,就会频繁的去走数据库查询。

? select_related 会自动做连表操作,然后将连表之后的数据全部查询出来封装给对象select_related括号内只能放外键字段,并且多对多字段不能放。如果括号内外键字段所关联的表中还有外键字段,还可以继续连表。select_related(外键字段__外键字段__外键字段...)

res = models.Book.objects.select_related('publish')

? prefetch_related看似连表操作,其实是类似于子查询prefetch_related括号内只能放外键字段 。并且多对多字段不能放 ,如果括号内外键字段所关联的表中还有外键字段,还可以继续连表 ,select_related(外键字段__外键字段__外键字段...)。

res = models.Book.objects.prefetch_related('publish')
print(res)
    for r in res:
        print(r.publish.name)

五、事务

? 事务的定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)。

? 事务的四大特点:

  1. 原子性;
  2. 持久性;
  3. 一致性;
  4. 隔离性。

? django中开启事务:

from django.db import transation
with transaction.atomic():
    # 在该代码块中所写的orm语句 同属于一个事务

# 缩进出来之后自动结束

肆拾捌 --- 模型层下

标签:状态   商品   隔离   自定义   auth   ext   ice   nosql数据库   product   

原文地址:https://www.cnblogs.com/tangceng/p/11748234.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!