Reputation: 198
I am using django and I am having a little trouble figuring out how to handle complex queries to the database. I have two models:
Parent:
id = models.AutoField(primary_key = True)
name = models.CharField(max_length = 60)
category = models.ForeignKey(Categories, on_delete = models.CASCADE)
And son:
id = models.AutoField(primary_key = True)
name = models.CharField(max_length = 60)
parent = models.ForeignKey(Parent, on_delete = models.CASCADE)
Basically, I have an object with a queryset of sons, and I need to filter this queryset by certain categories of the parent. For example, filter all sons where parent category is 9, 10 or 11.
I know how to use Q to do the OR part, but I don't know how to filter by a field in the parent.
Upvotes: 2
Views: 3955
Reputation: 353
You don't have to use Q
for this type of query. I would actually recommend keeping this simple as said in the zen of Python.
If you want those Son
objects which have their parents in categories 9, 10 and 11 (since you have a Categories
model as well, I am gonna suppose Categories
model has a field number
having respective category numbers), perform this query :
sons = Son.objects.filter(parent__category__number__in=[9,10,11])
One caveat however is, if you have to get parent
object of each Son
object in sons
Queryset (here, taking the first Son
object), you have to do sons.first().parent
which hits the database with one more query because Querysets are lazily evaluated.
To prevent this from happening, and fundamentally keeping database hits limited, do the below query (only if you are sure you'll need parent
object of Son
s) :
sons = Son.objects.filter(parent__category__number__in=[9,10,11]).select_related('parent')
This will pre-populate parent
for each Son
object in sons Queryset
.
Also, Models are named singular, so I would recommend changing
Categories
toCategory
Upvotes: 2
Reputation: 8525
Django offers a powerful and intuitive way to “follow” relationships in lookups.
Try this using Q
from django.db.models
Official Django Documentation
Son.objects.filter(Q(parent__cateogory__id='') | Q(parent__cateogy__name=''))
Upvotes: 2
Reputation: 2671
Try something like that:
sons = Son.objects.filter(parent__category__in = [9, 10, 11]).select_related('parent')
You have to use __
(double underscores) to access a ForeignKey model's
fields.
Upvotes: 7