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))
你是对的;我误解了预取相关的操作方式。你是对的;我误解了预取相关的操作方式。