Django如何合并相同或不同模型的两个查询集?

> Django的QuerySet查询为我们提供了一个union()的API,用于合并两个或多个查询集的结果集。查询集可以来自相同或不同的模型。当它们的查询集来自不同的模型时,字段及其数据类型应该匹配。

相同模型之间的合并

以Django自带的User模型为例:

>>> from django.contrib.auth.models import User
>>> User.objects.all()
<QuerySet [<User: admin>, <User: yonghu1>, <User: yonghu2>, <User: yonghu3>]>
>>> q1 = User.objects.filter(id__gte = 3)    # id大于等于3的用户
>>> q1
<QuerySet [<User: yonghu2>, <User: yonghu3>]>
>>> q2 = User.objects.filter(id__lt = 2)    # id小于2的用户
>>> q2
<QuerySet [<User: admin>]>
>>> q1.union(q2)   # 合并相同模型的查询集
<QuerySet [<User: admin>, <User: yonghu2>, <User: yonghu3>]>
>>> q2.union(q1)
<QuerySet [<User: admin>, <User: yonghu2>, <User: yonghu3>]>
>>>

不同模型之间的合并

下来我们再来看看不同模型之间如何合并,假如我们有一个UserProfile的模型,里边的字段包含了id,username,email,gender,phone,add_date,下来我们就合并一下User和UserProfile模型的查询集。

>>> from polls.models import UserProfile
>>> from django.contrib.auth.models import User

>>> user_profile = UserProfile.objects.all()
>>> user_profile
<QuerySet [<UserProfile: UserProfile object (1)>]>
>>> q1 = User.objects.filter(id__gte=3)
>>> q1
<QuerySet [<User: yonghu2>, <User: yonghu3>]>

>>> q1.union(user_profile)  #  合并两个不同的模型,这里出现错误
Traceback (most recent call last):
    ....
    return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: SELECTs to the left and right of UNION do not have the same number of result columns

注意union只能对具有相同字段和数据类型的查询集执行联合操作。因此,我们的这个联合操作遇到错误。但是django为我们提供了一个values_list的方法用来限制所选字段,所以只要我们选出这两个模型的相同字段进行合并即可成功。

我们知道User具有useranmeemail字段,正好我们的UserProfile模型中也有,因此上我们可以利用values_list用来限制所选字段,然后进行并集。

>>> User.objects.all().values_list('username', 'email').union(UserProfile.objects.all().values_list('username', 'email'))

# 查询集合并结果
<QuerySet [('admin', '2539909370@qq.com'), ('yonghu1', 'yonghu1@qq.com'), ('yonghu2', 'yonghu2@qq.com'), ('yonghu3', 'yonghu3@qq.com'), ('轻编程', '2539909370@qq.com')]>

评论 0