TIL
Web Dev Bootcamp TIL Day-51(Django ORM: Q() and _related)
frannyk
2022. 6. 25. 14:21
- Django's built-in query object Q() allows us to query data in an equivalent manner to SQL WHERE clauses.
from django.db.models import Q
q = Q()
q.add(Q(no=12121), q.OR)
q.add(Q(name=lee)|Q(name=kim), q.AND)
q.add(Q(142411), q.OR)
Base.objects.filter(q)
# equivalent to:
# SELECT * FROM base WHERE (no=12121 AND (name='lee' OR name='kim')) OR no=142411
- Q() comes in handy when we want to build lengthy queries, perhaps from a search parameter list
skills = request.query_params.getlist('skills', '')
# skills = ['Python', 'MySQL', 'Java', 'PostgreSQL', 'Node.js', 'React Native']
query = Q()
for skill in skills:
query.add(Q(skill_set__name=skill), Q.OR)
# Q(skillset__name='python') | Q(skillset__name='MySQL') | ...
job_skills = JobPostSkillSet.objects.filter(query)
- We can use select_related when the object that we are selecting is a single object such as:
- OneToOneField
- ForeignKey
- We use prefetch_related when we want to return a "set" of things:
- ManyToManyFields
- reverse ForeignKeys
class ModelA(models.Model):
pass
class ModelB(models.Model):
a = ForeignKey(ModelA)
ModelB.objects.select_related('a').all() # Forward ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all() # Reverse ForeignKey relationship
- The main difference between the two are that select_related does an SQL join and therefore gets the results back as part of the table from the SQL server.
- On the other hand, prefetch_related executes another query and therefore reduces the redundant columns in the original object (ModelA in the above example).
- Though we may use prefetch_related for anything that we can use select_related for, it is important to consider the cost efficiency of each query.
- select_related uses a JOIN in the SQL whereas prefetch_related runs the query on the first model, collects all the IDs it needs to prefetch and then runs a query with an IN clause in the WHERE with all the IDs that it needs.
- If you have say 3-5 models using the same foreign key, select_related will almost certainly be better.
- If you have 100s or 1000s of models using the same foreign key, prefetch_related could actually be better.