简体   繁体   中英

Django .values_list() alternative that returns a QuerySet for a ForeignKey field's model?

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.

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.

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

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.

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.

Try this, it will return query_set of Child class

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM