Django .values_list()替代方法为ForeignKey字段的模型返回QuerySet?

时间:2022-04-20 01:35:36

I'm looking for a clean way to convert one type of QuerySet to another based on a models ForeignKey field, so basically something like a .values_list('my_fk', flat=True) but returning a proper QuerySet instead of a values_list() variant.

我正在寻找一种基于模型ForeignKey字段将一种类型的QuerySet转换为另一种类型的干净方法,所以基本上类似于.values_list('my_fk',flat = True)但返回正确的QuerySet而不是values_list()变种。

For example:

class Parent(models.Model):
    child = models.ForeignKey(Child)
    ...

children_qs = Parent.objects.filter(...).theMagicMethod('child')  

Here children_qs should now be a queryset for all Child instances used in the earlier query, instead of a queryset returning Parent instance.

这里,children_qs现在应该是先前查询中使用的所有Child实例的查询集,而不是返回Parent实例的查询集。

You can sort of do this with a custom queryset and an __in lookup but it feels a bit smelly:

您可以使用自定义查询集和__in查找来执行此操作,但感觉有点臭:

class ParentQuerySet(models.QuerySet):
    ...
    def children(self):
        return Child.objects.filter(id__in=self.values_list('child_id', flat=True))

This takes all the child_id FK's from the records in the Parent's queryset and re-query Child directly. When I inspect the SQL it does a sub query, and I'm not sure if this is optimal or has some odd side effects. It does look like the ordering from the original Parent query is gone, and so are duplicates.

这将从Parent的查询集中的记录中获取所有child_id FK,并直接重新查询Child。当我检查SQL它做了一个子查询,我不确定这是否是最佳的或有一些奇怪的副作用。它看起来像原始父查询的排序已经消失,因此重复。

Does anyone got something better then this?

有没有人比这更好?

note: I'm aware I could query directly via Child and filter the Parent's fields using the reverse lookup, but that doesn't support everything you can do on the main model.

注意:我知道我可以通过Child直接查询并使用反向查找过滤Parent的字段,但这不支持您可以在主模型上执行的所有操作。

2 个解决方案

#1


3  

Try this, it will return query_set of Child class

试试这个,它将返回Child类的query_set

parent_primary_keys = Parent.objects.filter(...).values_list('pk',flat=True)

 children_qs = Child.objects.filter(id__in=parent_primary_keys)

#2


0  

It sounds like you can leverage the Django's function prefetch_related. Check out this answer and django's documentation

听起来你可以利用Django的函数prefetch_related。看看这个答案和django的文档

#1


3  

Try this, it will return query_set of Child class

试试这个,它将返回Child类的query_set

parent_primary_keys = Parent.objects.filter(...).values_list('pk',flat=True)

 children_qs = Child.objects.filter(id__in=parent_primary_keys)

#2


0  

It sounds like you can leverage the Django's function prefetch_related. Check out this answer and django's documentation

听起来你可以利用Django的函数prefetch_related。看看这个答案和django的文档