I have a Q&A type of site built in Django with the following models:
class Question(models.Model): title = models.CharField(max_length=70) details = models.TextField() class Answer(models.Model): question_id = IntegerField() details = models.TextField()
I need to display a specific question together with its answers. Normally I'd need 2 queries to do that:
Question.objects.get(id=1) Answer.objects.get(question_id=1)[:10]
I'm hoping to retrieve everything using one query. In MySQL it'd be:
SELECT * FROM Question JOIN Answer ON Question.id=Answer.question_id WHERE Question.id=1 LIMIT 10
Is there anyway I could do this through Django's ORM? Would extra()
help in this case?
10. Join Queries. Join can be done with select_related method: Django defines this function as Returns a QuerySet that will “follow” foreign-key relationships, selecting additional related-object data when it executes its query.
1 Answer. Show activity on this post. In your models Device and History models are related with a foreign key from History to DeviceModel, this mean when you have a History object you can retrieve the Device model related to it, and viceversa (if you have a Device you can get its History).
Use union operator for queryset | to take union of two queryset. If both queryset belongs to same model / single model than it is possible to combine querysets by using union operator. One other way to achieve combine operation between two queryset is to use itertools chain function.
This is exactly what select_related() does. The only gotcha is that you have to start with the Answer model, rather than Question, but the result is the same:
answers = Answer.objects.filter(question_id=1).select_related()
Now each answer object has a pre-fetched 'question' attribute, and accessing it won't hit the db again.
Consider using models.ForeignKey(Question)
instead of question_id = IntegerField()
.
This is the optimal (more relational) way to express the relationship between Questions and Answers you are trying to portray.
This way you can simply call Answers.objects.filter(question_id=<id>)
and get exactly what you're looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With