Django:过滤由联合体构成的查询集不起作用 [英] Django: Filter a Queryset made of unions not working

查看:131
本文介绍了Django:过滤由联合体构成的查询集不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我定义了3个与M2M关系有关的模型

I defined 3 models related with M2M relationsships

class Suite(models.Model):
    name = models.CharField(max_length=250)
    title = models.CharField(max_length=250)
    icon = models.CharField(max_length=250)

    def __str__(self):
        return self.title



class Role(models.Model):
    name = models.CharField(max_length=250)
    title = models.CharField(max_length=250)
    suites = models.ManyToManyField(Suite)
    services = models.ManyToManyField(Service)
    Actions = models.ManyToManyField(Action)
    users = models.ManyToManyField(User)

    def __str__(self):
        return self.title

在我的一种观点中,我试图收集与特定用户相关的所有套房。该用户可能与几个角色有关,这些角色可能包含许多 Suite 。然后按名称过滤套房。但是过滤器似乎没有作用

In one of my views I tried to collect all the Suites related to an specific User. The user may be related to several Roles that can contain many Suites. And then filter Suites by name. But the filter seem to have no effects

queryset = Suite.objects.union(*(role.suites.all() for role in 
self.get_user().role_set.all()))
repr(self.queryset)

'<QuerySet [<Suite: energia>, <Suite: waste 4 thing>]>'

self.queryset = self.queryset.filter(name="energia")
repr(self.queryset)

'<QuerySet [<Suite: energia>, <Suite: waste 4 thing>]>'

在执行过滤器之前,查询集中的查询属性不会更改其内容:

The query atribute inside the queryset not alter its content before executin the filter:

(SELECT "navbar_suite"."id", "navbar_suite"."name", "navbar_suite"."title", "navbar_suite"."icon" FROM "navbar_suite") UNION (SELECT "navbar_suite"."id", "navbar_suite"."name", "navbar_suite"."title", "navbar_suite"."icon" FROM "navbar_suite" INNER JOIN "navbar_role_suites" ON ("navbar_suite"."id" = "navbar_role_suites"."suite_id") WHERE "navbar_role_suites"."role_id" = 1)

(SELECT "navbar_suite"."id", "navbar_suite"."name", "navbar_suite"."title", "navbar_suite"."icon" FROM "navbar_suite") UNION (SELECT "navbar_suite"."id", "navbar_suite"."name", "navbar_suite"."title", "navbar_suite"."icon" FROM "navbar_suite" INNER JOIN "navbar_role_suites" ON ("navbar_suite"."id" = "navbar_role_suites"."suite_id") WHERE "navbar_role_suites"."role_id" = 1)


推荐答案

如<一个href = https://docs.djangoproject.com/zh-CN/2.0/ref/models/querysets/#union rel = noreferrer> django文档,仅 count() order_by() values() values_list( )并允许对联合查询集进行切片。您不能对联合查询集进行过滤。

As stated in django docs, only count(), order_by(), values(), values_list() and slicing of union queryset is allowed. You can't filter on union queryset.

这意味着,必须在对查询应用联合之前对查询应用过滤器。

That means, you have to apply filters on queries before applying union on them.

此外,即使不使用 union(),也可以实现目标:

Also, you can achieve your goal without even using union():

Suite.objects.filter(role_set__users=self.get_user(), name="energia")

如果在定义中使用了 related_name related_query_name ,则可能需要在过滤器中调整字段名称角色模型中的套房 M2M字段。

You may need to adjust field name in filter if you've used related_name or related_query_name in definition of suites M2M field in Role model.

这篇关于Django:过滤由联合体构成的查询集不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆