Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 过滤Django查询集';使用值()时,s相关的多个字段_Python_Django - Fatal编程技术网

Python 过滤Django查询集';使用值()时,s相关的多个字段

Python 过滤Django查询集';使用值()时,s相关的多个字段,python,django,Python,Django,我正在使用一个查询集,其中包括一个manytomy字段brand\u组。用户只能根据其组织访问品牌组的子集。我试图在仍然使用时过滤掉manytomy字段,它与视图集成度很高 我正在使用的简化表: class BrandGroup(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=256) organization = models.For

我正在使用一个查询集,其中包括一个
manytomy
字段
brand\u组
。用户只能根据其组织访问
品牌组的子集。我试图在仍然使用时过滤掉
manytomy
字段,它与视图集成度很高

我正在使用的简化表:

class BrandGroup(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=256)
    organization = models.ForeignKey(
        Organization, related_name="brand_groups", null=False
    )

class Fact(models.Model):
    id = models.CharField(max_length=256, primary_key=True)
    brand_groups = models.ManyToManyField(BrandGroup, blank=True)
过去对我有用的是使用
Prefetch
对象来处理这种限制:

qs = Fact.objects.prefetch_related(
    Prefetch("brand_groups",
        queryset=BrandGroup.objects.filter(
            organization_id=self.request.META["ORG_ID_HEADER"]
)))
但是我发现
values()
似乎完全忽略了预取

qs.values("brand_groups__name")
以上内容始终包括不带过滤器的全套关联
BrandGroup
对象

我曾尝试将
添加到
预回迁
的\u attr='org\u brand\u groups'
,但
qs.values(“org\u brand\u groups\u name”)
抱怨该字段不存在

我还尝试使用注释以类似的方式重命名预取字段。我没有收到关于字段不存在的投诉,但是再次
values()
返回未过滤的查询集

我成功完成此类筛选的唯一方法是使用子查询:

qs = Fact.objects.annotate(
    brand_group_name=Subquery(
        BrandGroup.objects.filter(
            organization_id=self.request.META["ORG_ID_HEADER"],
            Q(id=OuterRef("brand_groups__id"))).values(
                "name"[:1],output_field=CharField(),))

# Now it gives me the desired results
qs.values("brand_group_name")
但这种方法否定了我想要实现的目标。目标是使用联接而不是子查询来拉入
BrandGroup
数据


是否有任何方法可以过滤
manytomy
相关字段,而无需使用
values()
的子查询?我唯一剩下的想法是在应用了
values()
之后用Python过滤查询集。

我想你误解了:

另一方面,prefetch_-related对每个关系执行单独的查找,并在Python中执行“连接”。这允许它预取多对多和多对一对象,这是使用select_-related无法完成的,此外,select_-related还支持外键和一对一关系


您最好使用示例中的子查询

我想你误解了:

另一方面,prefetch_-related对每个关系执行单独的查找,并在Python中执行“连接”。这允许它预取多对多和多对一对象,这是使用select_-related无法完成的,此外,select_-related还支持外键和一对一关系


您最好使用示例中的子查询

最终,我在使用
值之前没有做任何过滤,在调用
值之后使用
存在的
过滤器

qs = Fact.objects.filter(...)
qs = qs.values("brand_groups__name", "brand_groups__id")

qs = qs.annotate(
    brand_group_accessible=Exists(
        BrandGroup.objects.filter(
            organization_id=self.request.META["ORG_ID_HEADER"],
            Q(id=OuterRef("brand_groups__id")))))

qs = qs.filter(Q(brand_group_accessible=True) | Q(brand_groups__id__isnull=True))

最终,我在使用
值之前没有做任何过滤,在调用
值之后使用
存在的
过滤器

qs = Fact.objects.filter(...)
qs = qs.values("brand_groups__name", "brand_groups__id")

qs = qs.annotate(
    brand_group_accessible=Exists(
        BrandGroup.objects.filter(
            organization_id=self.request.META["ORG_ID_HEADER"],
            Q(id=OuterRef("brand_groups__id")))))

qs = qs.filter(Q(brand_group_accessible=True) | Q(brand_groups__id__isnull=True))

你是对的;我误解了预取相关的操作方式。你是对的;我误解了预取相关的操作方式。