41

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?

4 Answers 4

66

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, what if we need name of foreign key on related table, suppose table A is related to B and B is related to C. (all tables only have "name" and "id"). we want join that every entry of A shown side by related C table object.
How can this work if question_id is just an integer, and Answer does not provide a models.ForeignKey field to Question?
49

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.

1 Comment

Using a ForeignKey is indeed the right way to go, but the query call offered in this answer only returns Answer objects, while the question was how to get the Question and Answer objects in one query.
15
    class Question(models.Model):
      title = models.CharField(max_length=70)
      details = models.TextField()

    class Answer(models.Model):
      question = models.ForeignKey('Question')
      details = models.TextField()

    id = <whatever_id>    
    answers = Question.objects.get(id=id).answer_set.all()

1 Comment

id is a built in function now, may not have been in 2015
4

#Consider A Foreign Key Relationship Between Books And Publisher

class Publisher(models.Model):
 name = models.CharField(max_length=100)

eclass Book(models.Model):
 publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)

#Fetch Publisher Name For A Book

book = Book.objects.select_related('publisher').get(id=1)
book.publisher.name

#Fetch books which have specific publisher

publisher = Publisher.objects.prefetch_related('book_set').get(id=1)
books = publisher.book_set.all()

for more https://kwikl3arn.com/django/JOINS

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.