Django ORM模型:想说爱你不容易

  • 时间:
  • 浏览:4
  • 来源:大发uu快3_uu快3开奖历史_大发uu快3开奖历史

作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载。

使用Python的Django模型语句,一般后要用它自带的ORM(Object-relational mapping)模型。你这一ORM模型的设计比较简单,学起来不用不得劲花时间。不过,Django的ORM模型有此人 的一套语法,有后后要着实别扭。这里聊一下我此人 的体会。

模型设计

你这一要素算避免得比较好的要素。Django的数据模型的建立过程很简单,过多过多 我继承django.db.models中的Model类,有后后给它增加属性。每有三个多 属性可以对应关系数据库中的有三个多 字段。比如在有三个多 叫myapp的Django App下,创建models.py文件:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=10)

通过manage.py的makemigrations和migrate命令,就可以执行数据库的迁移。后面 的name属性,就对应了生成的myapp_person表中名为"name"的一列。这里的max_length=10对应了限制条件:

(在MySQL V4中,代表了10个字节;在MySQL V5中,代表了10个字符。)

除了后面 的字符类型,一点常见的字段类型,在Django全版后要对应的*Field来表达,比如TextField、DateField、DateTimeField、IntegerField、DecimalField。此外,还有一点常见的限制条件,除了后面 的max_length,还有default、unique、null、primary_key等等。数字类型的限制条件有max、min、max_digits、decimal_places。那些限制条件都通过参数的形式传给属性。有一点限制条件是Django提供的,并没法 数据库层面的对应物,比如blank。

(当blank参数为真时,对应字段可以为留为空白。)

在基本的模型设计上,Django ORM没法 留那些坑。

关系

Django中的一对一、多对一、多对多关系可以通过下面最好的方法表达:

from django.db import models


class Company(models.Model):
    name = models.CharField(max_length=10)


class Group(models.Model):
    name = models.CharField(max_length=10)


class Person(models.Model):
    name = models.CharField(max_length=10)


class Customer(models.Model):

name = models.CharField(max_length=10) person
= models.OneToOneField(Person) company = models.ForeignKey(Company, on_delete=models.CASCADE) groups = models.ManyToManyField(Group)

Customer的定义中,用到一对一、多对一、多对多关系。它们分别通过OneToOneField、ForeignKey和ManyToManyField来实现。

必须注意的是,在Django ORM中,必须通过ForeignKey来定义多对一关系,必须显示地定义一对多关系。但我就使用模型对象的*_set语法来反向调用多对一关系。比如说:

company.customer_set   #company是有三个多

Company的实例

就可以根据一对多关系,调到该公司下的所有客户。此外,多对多关系不可以不能用之类 的最好的方法反向调用,比如:

此外,你还可以在模型中加入related_name参数,从而在反省调用时,改用"*_set"之外的一点名称,比如:

class Customer(models.Model):
   person  = models.OneToOneField(Person)
   address = models.CharField(max_length=400)
   company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name="customers")

因为 有三个多 模型之间有多个关系时,related_name可以避免*_set重名。

总的来说,后面 的避免方案可以实现功能,无须影响使用。但我一个劲着实你这一避免方案一点丑陋。因为 必须显式地表达有三个多 模型之间的关系,模型之间的关系看起来存在问题明了。不得劲是读代码时,第有三个多 类定义全版没法 提示一对多的关系。我必必须看多了第五个类定义,不可以搞明白有三个多 模型之间的关系。真希望有有某种显式说明关系的最好的方法,降低读代码时的认知负担。

查询

Django ORM可以通过一点最好的方法来实现。其中的过多过多 最好的方法返回的是Django自定义的QuerySet类的迭代器。Python看多迭代器后要懒惰求值,过多过多 那些最好的方法返回时无须会真正进行数据库操作。过多过多 我,多个最好的方法串联操作时,就避免了重复操作数据库。返回QuerySet的常见最好的方法包括:

all()
filter()
exclude()
annotate()
order_by()
reverse()
distinct()
...

对于依赖具体数据的操作,QuerySet会求值。比如遍历QuerySet时,就会先执行数据库操作。用len()获得QuerySet长度时,也会造成QuerySet估值。此外QuerySet一点最好的方法,比get()、count()、earlist()、exists()等,后要对QuerySet进行求值。有后后,在写线程时,要注意QuerySet求值的时间点,避免重复的数据库操作。

SQL的WHERE条件可以通过参数的形式来传给最好的方法。那些参数一般是"[字段]__[运算符]"的命名最好的方法,比如:

Customer.objects.filter(name__contains="abc")

除了contains,还有in、gt、lt、startswith、date、range等等操作符,能实现的WHERE条件着实够全的了。

不过,这又是有三个多 不得劲别扭的地方,即通过命名最好的方法来控制查询行为。我看多有的ORM是用lambda的形式来表达WHERE条件,还有的会做有三个多 之类 于contains()的最好的方法,全版后要比Django ORM的最好的方法好看。因为 是跨表查询,Django的最好的方法就更丑了:

Customer.objects.filter(company__name__contains="xxx")

无限的双下划线啊……

聚合

Django实现聚合的最好的方法青春恋爱物语是噩梦。貌似ORM对表达GROUP BY很无力,源代码里的注释就认输了:

聚合的aggregate()和annotate()最好的方法可以实现基本的功能,但稍微错综复杂一点,代码就变得魔幻了:

看多一大串values()、annotate()变来变去,有没法 着实头晕?我着实你这一具体情况下,可以直接上原始的SQL查询语句了,没必要再此人 折腾此人 。

F表达式和Q表达式

F表达式指代了一列,对于update操作时引用列的值有用。Q表达式代表了WHERE的有三个多 条件,可以用于多个WHERE条件的连接。那些全版后要Django ORM用来弥补存在问题的。就拿Q表达式来说。查询最好的方法中跟多个参数语句,合适多个WHERE条件。那些条件会默认为AND关系。为了表达OR和NOT关系,Django ORM就造了个Q表达式,比如:

filter(Q(name__contains="abc")|Q(name__startswith("xxx")))

为了弥补存在问题,Django ORM又增加了有某种语法风格。于是,学习路上又多了有三个多 坑……

总结

总的来说,Django ORM在实现基础的数据库操作方面没大问题。但因为 必须构建错综复杂的SQL语句,与其在Django ORM里绕来绕去,还不如直接用原始的SQL语句。你这一是我最强烈的有三个多 感受。当然,Django ORM还是可用的工具。我写这篇文章的目的,是提醒亲戚亲戚大伙儿儿无须误把糟糕的设计当做精巧的语法。

猜你喜欢

學好中文 人生贏家敲門磚

圖:蘇發努馮大學孔子學院在老撾第二大城市琅勃拉邦,有一座僅次於國立大學的高校:蘇發努馮大學。從校門進入繞過寬大的草坪就能就看「孔子學院」的指示牌,院長張明虎(左圖)說雖然他們才

2020-01-20

Antonio Montiel数据,Antonio Montiel新闻,Antonio Montiel视频,Antonio Montiel身价

首页新闻视频直播数据APP懂球号直播君广告合作协议方式AntonioMontielAntonioMontiel俱乐部:国籍:西班牙身高:184CM位置:球员年龄:29岁体重:7

2020-01-20

暗示防长要下台?特朗普:马蒂斯“像民主党人”

美国防部长詹姆斯·马蒂斯。(图源:美联社)美国总统唐纳德·特朗普在当地时间周日(14日)曝光的一段公开采访片段中表示,国防部长詹姆斯·马蒂斯(JamesMattis)“一阵一阵

2020-01-20

阿姆利奥VS贝里奥免费视频直播,阿姆利奥VS贝里奥比赛集锦,阿姆利奥VS贝里奥录像,阿姆利奥VS贝里奥首发阵容

首页新闻视频直播数据APP懂球号直播君广告公司合作 阿姆利奥05-0600:00西丙2-5已始于贝里奥直播君|分析|集锦暂无数据近期比赛萨索洛意甲2-1都灵纽卡斯尔联英超1-

2020-01-20

欧迪兹亚VS德乌斯托免费视频直播,欧迪兹亚VS德乌斯托比赛集锦,欧迪兹亚VS德乌斯托录像,欧迪兹亚VS德乌斯托首发阵容

首页新闻视频直播数据APP懂球号直播君广告商务战略合作欧迪兹亚05-0523:00西丙1-2已开始德乌斯托直播君|分析|集锦暂无数据近期比赛萨索洛意甲2-1都灵纽卡斯尔联英超1

2020-01-20