如何将模型实例添加到django查询集?

时间:2015-04-12 08:13:12

标签: python django

似乎django查询集在某种程度上表现得像python列表。

但据我所知,它并不支持list的.append()方法。

我想做的是:

from my_django_app.models import MyModel

queryset = MyModel.objects.none()
queryset.append(MyModel.objects.first())      ## no list's .append() method!

有没有办法将模型实例添加到现有的查询集?

4 个答案:

答案 0 :(得分:12)

没有。查询集是查询的表示 - 因此是名称 - 而不是任意实例集合。

如果您确实需要实际的查询集而不是列表,可以尝试累积所需对象的ID,然后通过__in查询获取对象:

list_of_ids = []
list_of_ids.append(my_id)
...
queryset = MyModel.objects.filter(id__in=list_of_ids)

但这并不是非常有效。

答案 1 :(得分:9)

您还可以使用|运算符创建联合:

queryset = MyModel.objects.none()
instance = MyModel.objects.first()
queryset |= MyModel.objects.filter(pk=instance.pk)

但请注意,这将生成不同的查询,具体取决于您以这种方式追加的项目数,使得编译查询的缓存效率低下。

答案 2 :(得分:2)

Queryset不是list

所以

to_list = queryset.values()

合并queryset

from itertools import chain
result_queryset = list(chain(queryset1, queryset2))

querysets = [queryset1, queryset2]
result_queryset = list(chain(*querysets))

答案 3 :(得分:1)

可以使用union完成此操作。完成此操作后,结果的类型可以视为<class 'django.db.models.query.QuerySet'>。因此,可以组合两个查询集。让我们来看一个例子。

query1 = User.objects.filter(is_active=True)

query2 = User.objects.filter(is_active=False)

combined_query = query1.union(query2)

print (type(combined_query))

上面的程序将打印结果如下,确认它是一个查询集

<class 'django.db.models.query.QuerySet'>

因此,基本上Django对联合执行以下查询。

(SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = True) 
UNION 
(SELECT "auth_user"."id", "auth_user"."password", "auth_user"."last_login", "auth_user"."is_superuser", "auth_user"."username", "auth_user"."first_name", "auth_user"."last_name", "auth_user"."email", "auth_user"."is_staff", "auth_user"."is_active", "auth_user"."date_joined" FROM "auth_user" WHERE "auth_user"."is_active" = False)

这还意味着,如果尝试使用两个不同的表进行联合,则会出现错误(django.db.utils.ProgrammingError: each UNION query must have the same number of columns)。