Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: implementing JOIN using Django ORM?

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?

like image 535
Continuation Avatar asked Nov 08 '10 15:11

Continuation


People also ask

How do you join an operation in Django ORM?

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.

How do I merge two Django models?

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).

How do I join a query set in Django?

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.


2 Answers

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.

like image 59
Daniel Roseman Avatar answered Oct 24 '22 20:10

Daniel Roseman


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.

like image 22
baklarz2048 Avatar answered Oct 24 '22 21:10

baklarz2048