Reputation: 4954
Lets say I have the following models:
class ParentModel(models.Model):
name = models.CharField()
child = models.ForeignKey("ChildModel")
class ChildModel(models.Model):
name = models.CharField()
Now, given some filter on ParentModels, I want to retrieve a list of all children models. I have tried:
children = ParentModel.objects.filter(name__startswith='A').values_list('child', flat=True)
However this returns a list of ChildModel ids, rather than the full objects. Is there a queryset function that will accomplish what I am trying to do or do I need to write an additional filter query using the returned ids? I.e.- instead of:
children => [51L, 53L, 54L]
I want:
children => [<ChildModel: ChildModel Object>, <ChildModel: ChildModel Object>, <ChildModel: ChildModel Object>]
Upvotes: 17
Views: 29887
Reputation: 3472
This one was an active issue on the Django site: https://code.djangoproject.com/ticket/8144
You have two options:
I know how to implement option 2, so here is my approach:
Option #2:
children_ids = ParentModel.objects.filter(name__startswith='A').values_list('child', flat=True)
children = ChildModel.objects.filter(pk__in=children_ids)
Upvotes: 5
Reputation: 359
I think you may want to refactor your models to be something like:
class ParentModel(models.Model):
name = models.CharField()
class ChildModel(models.Model):
name = models.CharField()
parent = models.ForeignKey(ParentModel)
Then you can just do the following to receive a queryset list of ChildModel
:
ParentModel.childmodel_set.all()
This would be interpreted as "each ParentModel can have many ChildModel's."
Upvotes: 6
Reputation: 600049
You can use a subquery with __in
:
Child.objects.filter(parent__in=Parent.objects.filter(name__startswith='A'))
(Note, your naming is a bit odd here: usually the child is the one with the foreign key, since it assumes that a parent can have multiple children.)
Upvotes: 25