毎日のジャンゴ - モデル層(2)

毎日のジャンゴ - モデル層(2)

いくつかの一般的なクエリ

集計クエリ

集計では、我々は文字通りに言えば、重合、データベースのSQL言語での集計関数の概念ので、この概念を持っている必要があり、物事のクラスを一緒に置くことであるが、彼らはグループ化と同じではありません。

我々は、我々はSQL文、GROUPBYのグループ化と集計関数を記述する際、パケット内のselect文たら、次に我々は唯一のフィールドと集計関数の数からなるフィールドでグループに問い合わせることができるので、不可分であるということはありません知っていますフィールドの裏に書かれたとすると、エラーが選択されます。

だから、今ORMは、データベースを操作するために使用されていることを、我々は集計クエリ時間を使用し、以下のように、我々は、集計クエリの特定の使用の法律に従う必要があります。

# 首先导入聚合函数,聚合函数的关键字为aggregate
from django.db.models import Max,Min,Sum,Count,Avg

# 大概格式为:models.表名.objects.查询方式(匹配条件).aggregate(聚合函数(表中的字段))
res = models.Book.objects.all().aggregate(Avg('price'))
print(res)

クエリをグループ化

キーワードのグループ化クエリは、データベースの実際の動作では、非常に簡単な使用、注釈を付けることで、実際にGROUPBY、操作の後の括弧内のグループにテーブル名の後ろのモデル、およびデータパケットのために従いますクエリをグループ化します

# 分组查询的格式为:models.表名.objects.annotate(对组内数据做操作)
res = models.Book.objects.annotate(author_number=Count('authors').values('author_num'))
print(res)

FとQの問合せ

上記の集約とグループ化クエリは、私たちのフィールドの表から削除した後、私たちは、比較のためにデータベースの2つの異なるフィールドから値を取得する必要がある場合は、シナリオを想定、一定の良い比較で設定されていますどのようにそれを達成するには?この問題を解決するために私たちにFとQのクエリを与えたDjangoに。

from django.db.models import F,Q
res = models.Book.objects.filter(sell = F('kucun'))
print(res)
# 以上语句可以实现在Book表中,我们以kucun列为依据,来查询得到自己想要的数据,甚至可以在查询的时候直接对数据做操作,比如
res = models.Book.objects.filter(sell = F('kucun')+100)
print(res)

# 而Q查询比F查询更加强大,比如以下情景
# 我们需要根据不止一个条件来筛选记录,而且这些条件并不是and关系,而是or,或者not,此时就可以使用Q查询来解决问题,比如:
res = models.Book.objects.filter(Q(title='python')|Q(kucun=666))
res1 = models.Book.objects.filter(~Q(title='python')|Q(kucun=666))
print(res,res1)
# 以上两个例子,在两个Q之间用|是or的意思,即两者只要有一个成立就算符合条件,~则是取反的意思

以下のような、より良い利用があり、我々はQクエリが実際にクラスであることを知っているので、我々は、オブジェクトをインスタンス化することによって生成され、その後、オブジェクトを操作することによって、Qクエリおよびデータのスクリーニングの目的を実現するためにQクエリ、

from django.db.models import Q
q = Q()
q.connector = 'or'  # 这里可以直接配置其查询的方式,可以是or,可以是not
q.children.append(('title','python'))
q.children.append(('kucun',666))
res = models.Book.objects.filter(q)
print(res)

関連クエリの最適化

一般的にはORMのクエリの最適化は、4つのより一般的に使用される方法があるでしょう、彼らは唯一と、延期select_relaterとprefetch_related、のいずれかによって導入された1つの使用を比較してみましょうことを、ペアです。

only和defer('字段')
    首先他们的用法都是在关键字后面括号中加入表中有的字段.
    only会将括号内字段对应的所有数据直接封装起来,然后返回给我们的对象中,因为only()最后返回的是一个对象,然后我们对这个对象来进行操作的时候,如果点出来的是之前括号内的字段,那么此次查询就不会再经过数据库,但是如果点出来是括号内不包含的字段,那么每次都会重新查询数据库.
    做一个类比来说,only后面括号内字段所对应的数据相当于是拿出来放在了计算机的缓存中,我们在查询这个字段的时候就直接从缓存里取,而不需要再去查询数据库,可以节约大量查询的时间,当然这只是一个类比,实际情况并不是缓存的概念.
    defer的用法就和only完全相反,defer后面括号内字段对应的数据,在每次查询的时候都需要查询数据库,而括号内不包含的字段对应的数据查询则不需要查询数据库.
    个人理解only和defer的用法,only应该是用在不常修改的字段,也就是说only后面括号内的字段应该是修改次数尽量少的字段,这样既能提升效率,查询出来又不会出错.同理,defer后面括号内则是应该写频繁修改的字段,需要实时监控其变化的那种字段,比较合适.
select_relater和prefetch_related('外键关联表的表名')
    首先,select_relater和prefetch_related的共同点在于其传参的规则是相同的,其后面的括号里面都只能放外键字段,且只能放一对一和一对多的外键字段,不能放多对多的字段,而且可以叠加,即可以select_related(外键字段__外键字段__外键字段)这样放.
    select_related会自动帮我们做连表操作,这些表必须是有外键相关联的,select_related将连表之后的数据全部查询出来,然后封装起来,传给对象.
    而prefetch_related看似也是一个连表操作,其实不是,prefetch_related实际上是一种类似子查询的存在,其会多次查询不同的表,然后把最后的结果返回出来.
    这两种方法的区别在于
    第一种,内部自动连表,消耗的资源和时间都在连表上,对数据库的操作比较少,数据库压力小
    第二种,内部不做连表,消耗的资源和时间都在对数据库的查询上,数据库压力较大,但是整体效率较高

ORM共通フィールド

ORMは、我々models.py定義テーブル型フィールドである一般的に使用される使用されるカスタムフィールド、の形式は次のとおりです。

# 自增的数字,常用来设置主键,primary_key = True就为主键
AutoField(primary_key = True)

# 最常用的字符类型,相当于python中的varchar,max_length为其最大长度,超过这个长度的会被舍弃
CharField(max_length=32)

# 整型,默认括号内为空
IntegerField()

# 时间格式,常用参数有两个:
DateField()
    auto_now:每次对对象进行操作都会更新当前时间
    auto_now_add:在创建或添加对象的时候会添加这个时间,然后不会改变
# 小数格式的数字,max_digits为数字的总位数,decimal_places为数字的小数的位数
DecimalField(max_digits=8,decimal_places=2)
# 布尔类型,存储到数据库中的时候是0/1,并不是True和False
BooleanField()

ORMのトランザクション操作

私たちは、トランザクションデータベースがあることを知って、トランザクションは、ACID 4つの特性であります

  1. 不可分性

  2. 一貫性

  3. 隔離

  4. 持久性

    だから我々はまた、事務の存在を必要とするORM。次のことを行うには

from django.db import transaction
with transaction.atomic()
    #这里写的所有ORM语句都属于同一个事务
# 事务的结束标志就是这一个缩进

おすすめ

転載: www.cnblogs.com/Xu-PR/p/11753538.html