ORM表关系与查询操作

一、ORM的定义与表关系

1.定义
ORM,全称Object Relational Mapping,中文叫做对象关系映射,通过ORM我们可以通过类的方式去操作数据库。

2.外键
在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam。如果使用的是InnoDB引擎,是支持外键约束的。外键的存在使得ORM框架在处理表关系的时候异常的强大。

如下面两个表:


class User(models.Model):
    username = models.CharField(max_length=20)
    password = models.CharField(max_length=100)

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey("User",on_delete=models.CASCADE)

类定义为class ForeignKey(to,on_delete,\*\*options)。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有CASCADESET_NULLPROTECTSET_DEFAULTSET()DO_NOTHING等。

3.表关系
3.1一对多:
实现方式:一对多或者多对一,都是通过ForeignKey来实现的。

user = User.objects.first()
# 获取第一个用户的用户名
username = user.username
# 获取第一个用户写的所有文章
articles = user.article_set.all()

如果不想使用模型名字小写_set的方式,想要使用其他的名字,那么可以在定义模型的时候指定related_name
例如:

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    # 传递related_name参数,以后在方向引用的时候使用articles进行访问
    author = models.ForeignKey("User",on_delete=models.SET_NULL,null=True,related_name='articles')

于是获取第一个用户写的所有文章可以
articles = user.articles.all()

3.2一对一
实现方式:Django为一对一提供了一个专门的Field叫做OneToOneField来实现一对一操作。

3.3多对多

实现方式:Django为这种多对多的实现提供了专门的Field叫做ManyToManyField

二、ORM的查询操作需要注意的地方

1. 根据关联的表进行查询:
假如现在有两个ORM模型,一个是Article,一个是Category。比如想要获取文章标题中包含"hello"的所有的分类。那么可以通过以下代码来实现:


categories = Category.object.filter(article__title__contains("hello"))

2. 聚合函数:
以使用聚合函数来提取数据,通过aggregate方法实现。使用方法如下所示:

from django.db.models import Avg

result = Book.objects.aggregate(Avg('price'))
print(result)
>>>{"price__avg":23.0}


result1 = Book.objects.aggregate(my_avg=Avg('price'))
print(result1)
>>>{"my_avg":23}

其中price__avg的结构是根据field__avg规则构成的。如果想要修改默认的名字,那么可以将Avg赋值给一个关键字参数。

aggregate和annotate的区别:

 from djang.db.models import Sum
 result = Book.objects.annotate(total=Sum("bookstore__price")).values("name","total")

比如以上Sum的例子,如果使用的是annotate,那么将在每条图书的数据上都添加一个字段叫做total,计算这本书的销售总额。而如果使用的是aggregate,那么将求所有图书的销售总额。

aggregate:返回使用聚合函数后的字段和值。
annotate:在原来模型字段的基础之上添加一个使用了聚合函数的字段,并且在使用聚合函数的时候,会使用当前这个模型的主键进行分组(group by)。

3. F表达式与Q表达式:
示例代码如下:

from djang.db.models import F, Q

Employee.object.update(salary=F("salary")+1000)

books = Book.objects.filter(Q(price__lte=10) | Q(rating__lte=9))

F表达式和Q表达式都用于优化ORM的流程,不需要先把数据从数据库提取出来,操作完之后再保存回去,而是直接执行SQL语句。

当只是动态地获取某个数据或是将它进行简单的操作是,用F表达式。
当需要用到 | 、&和~(非)等复杂查询操作时,选择Q表达式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值