2017-09-29 12 views
0

J'essaie de comprendre l'utilisation de prefetch_related et select_related pour l'optimisation. J'ai appris quelque part dans le blog que l'un des endroits où utiliser prefetch et select est prefetch_related est utilisé pour la relation inverse et select_related pour la relation forward. Dans mon cas, il y a un modèle de CV et un modèle d'éducation. Le modèle d'éducation a FK de resume avec le nom associé pour la relation inverse au lieu d'écrire _set supplémentaire lors de l'interrogation. J'ai besoin de lister toute la formation d'un utilisateur demandé avec le CV de l'utilisateur demandé. Je pouvais le faire sans ces techniques d'optimisation comme suivreAttributeError: L'objet 'Resume' n'a pas d'attribut 'prefetch_related'

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

Lorsque j'ai essayé d'utiliser ce qui suit à la place, je reçois l'erreur je l'ai dit dans le titre

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

Voici mon modèle

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

Quelqu'un peut-il me rendre clair sur select_related et prefetch_related avec de simples termes simples? Je ne comprenais pas la question que je reçois

Répondre

2

de l'exception que vous avez fourni, vous essayez d'appeler .prefetch_related() sur l'objet Resume, pas Resume s QuerySet.

Donc, assurez-vous que vous exécutez

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

pas

Resume.objects.get(applicant=request.user).prefetch_related('educations') 
+0

De cette façon, je reçois seulement une requête au lieu de tous – milan

+0

@milan que voulez-vous dire par un 'QuerySet'? –

0

d'abord passer par ce [document prefetch_related] [1]

[1]: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#prefetch-related alors vous constaterez que vous ne pouvez pas l'utiliser comme ceci

vous devez appliquer sur l'éducation modale

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

espérons que cela vous aidera.

+1

Merci pour la solution. Je vais vérifier tout le lien que vous avez tous mentionné pour moi. Avant d'aller à ce lien, je ne suis pas sûr que je vais y entrer ou pas alors je veux demander quel est ce résumé dans prefetch_related. Est-ce le champ (fk) dans la table de l'éducation? – milan

+0

oui reprendre dans prefetch_related est fk dans la table de l'éducation. –

1

En fait, vous devriez utiliser select_related dans ce cas. Pour autant que je sache, prefetch_related est utilisé pour de nombreuses relations et il fait deux requêtes pour récupérer des objets alors que select_related est utilisé pour les relations normales fk ou one to one et récupère tous les objets dans une requête utilisant des jointures.