1

I am trying to understand the use of prefetch_related and select_related for optimization. I learned somewhere in the blog that one of the where to use prefetch and select is, prefetch_related is used for reverse relation and select_related for the forward relation. In my case there is Resume model and Education Model. Education model has FK of resume with the related_name for reverse relation instead of writing additional _set when querying. I need to list all the education of an requested user with the requested user resume. I could do this without those optimization techniques as follow

education_instance = Resume.objects.get(applicant=request.user).educations.all()

When I tried to use the following instead, I get the error I stated in the title

education_instance = Resume.objects.filter(applicant=request.user).prefetch_related('educations')

Here is my model

class Resume(models.Model):
    applicant = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=100, blank=False, null=False, help_text="Full Name")

class Education(models.Model):
    resume = models.ForeignKey(Resume, related_name='educations')
    name = models.CharField(max_length=100, blank=False, null=False, help_text="Name of an institution")

Can anyone make me clear on select_related and prefetch_related with simple layman terms ? I could not understand the issue I am getting

milan
  • 2,409
  • 2
  • 34
  • 71

3 Answers3

4

From the Exception that you provided, you are trying to call .prefetch_related() on object Resume, not Resumes QuerySet.

So, make sure you run

Resume.objects.filter(applicant=request.user).prefetch_related('educations')

not

Resume.objects.get(applicant=request.user).prefetch_related('educations')
vishes_shell
  • 22,409
  • 6
  • 71
  • 81
1

Actually you should use select_related in this case. As far as i know prefetch_related is used for many to many relations and it makes two queries to retrieve objects while select_related is used for normal fk or one to one relations and it fetched all objects in one query using joins.

Copperhead
  • 76
  • 4
0

first of all go through this [document of prefetch_related][1]

[1]: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#prefetch-related then you will find that you can not use it like this

you have to apply on Education modal

education_instance = Education.objects.filter(resume__applicant == request.user).prefetch_related('resume')

hope this will help you.

bhatt ravii
  • 382
  • 3
  • 12
  • 1
    Thank you for the solution. I will sure look at all the link you all have referred for me. Before going to that link, I am not sure I will get into it or not so I want to ask what is that resume inside prefetch_related. Is it the field(fk) in Education table? – milan Sep 29 '17 at 14:43
  • yes resume in prefetch_related is fk in Education table. – bhatt ravii Oct 02 '17 at 04:54