2017-08-11 2 views
0

Disons que je fais une recherche Workplace s dans un City et prefetch tous leurs Worker s, ce qui est un many-to-many:Est-ce que les opérations QuerySet sur les relations prélectées touchent la base de données?

workplaces = list(city.workerplace_set.filter(num_employees__lte=350).prefetch_related('Worker')) 

Si j'utilise de l'un des Workplace de toute opération QuerySet sur Worker s , la base de données sera-t-elle touchée ou non? Je n'ai pas pu trouver une réponse claire des docs.

workplaces_with_interns = [workplace for workplace in workplaces 
          # is this filter going to query the database? 
          if workplace.worker_set.filter(salary=0).exists()] 

PS: quelqu'un va probablement dire que je peux atteindre la même réponse en faisant simplement une requête pour city.workerplace_set au lieu d'en faire un list. Oui, je sais, mais ce n'est pas possible parce que je suis la mise en cache le workplaces afin que la base de données ne soit pas atteinte à chaque fois que la fonction qui fait tout cela est appelée.

Répondre

0

Oui. Cela va frapper la base de données parce que vous exécutez une requête spécifique - existe sur un filtre - qui n'était pas présente dans la prélecture d'origine.

Dans votre cas, puisque vous avez déjà les travailleurs, il serait préférable de les filtrer en Python:

[workplace for workplace in workplaces 
if any(w.salary == 0 for w in workplace.worker_set.all())] 

Sinon, si cela est la seule raison pour laquelle vous avez besoin du prefetch, vous pouvez utiliser une prélecture objet dans la requête d'origine pour récupérer uniquement les travailleurs avec 0 salaire.

(Vous avez remarqué que vous utilisez la version 1.4, qui ne contient pas d'objets Prefetch.) Vous devez certainement mettre à niveau, non seulement parce que 1.4 est très ancien et non pris en charge.

+0

Donc toute autre requête autre que 'workplace.worker_set.all()' touchera la base de données? – dabadaba