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

  • 时间:
  • 浏览:0
  • 来源:大发快3_快3在线稳定计划_大发快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=200)
   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-26

213.家庭账务管理信息系统

相关文件下载开发环境:win10_x64开发语言:Java(v1.8)和sql(v5.7)开发工具:eclipse和MySQL运行环境:win10_x64//Moneymana

2020-01-26

京东生鲜2018年战报:订单量同比增长80%

站长之家(ChinaZ.com)2月25日消息:近日,京东生鲜发布2018年年度战报。据数据显示,2018年京东生鲜订单量同比增长率达150%,店铺数量增长近1倍,月销过百万商

2020-01-26

大流量下的 ElasticSearch 搜索演进

这是泥瓦匠(bysocket.com)的第27篇精华分享ES(ElasticSearch)是分布式搜索引擎。引擎太晦涩,确实同类另另2个 MySQL,另另2个 存储。方便提

2020-01-25

关于解决特色小镇建设用地问题政策建议

核心提示:正确处理特色小镇建设用地的基本思路是存量土地挖潜提高速率,增量用地在土地使用计划中保证机会城乡建设用地增减挂钩正确处理,结合农村集体建设用地改革让集体建设用地通过入股

2020-01-25