Использование select_related в простом запросе в django
У меня есть модель в Django, в которой поле имеет fk отношения с моделью учителя. Я столкнулся с select_related в django и хочу использовать его в своем представлении. Однако я не уверен, использовать его в моем запросе или нет.
Мои модели:
class Teacher(models.Model):
name = models.OneToOneField(max_length=255, default="", blank=True)
address = models.CharField(max_length=255, default="", blank=True)
college_name = models.CharField(max_length=255, default="", blank=True)
class OnlineClass(models.Model):
teacher = models.ForeignKey(Teacher,on_delete=models.CASCADE)
Мое мнение:
def get(self, request,*args, **kwargs):
teacher = self.request.user.teacher
classes = Class.objects.filter(teacher=teacher) #confusion is here..............
serializer_class = self.get_serializer_class()
serializer = serializer_class(classes,many=True)
return Response(serializer.data,status=status.HTTP_200_OK)
Я прокомментировал строку или раздел задачи. Я хотел перечислить все классы этого учителя. Здесь я использовал filter. Но можно ли здесь использовать select_related? Как я понял, если я хочу показать и другие поля модели преподавателя, например, имя или название_колледжа, то я должен использовать его. В противном случае, то, как я это сделал, правильно. Кроме того, select_related используется только для get api, а не для post api, правильно ли это?
select_related
используется для выбора дополнительных данных из связанных объектов при выполнении запроса. Это приводит к более сложному запросу. Но это повышает производительность, если вам нужно получить доступ к связанным данным, поскольку не потребуется дополнительных запросов к базе данных.
См. документацию здесь.
В вашем коде можно было бы использовать select_related
, но id был бы неэффективным, поскольку вы не обращаетесь к связанным объектам запрашиваемых классов. Поэтому использование select_related
привело бы к более сложному запросу без каких-либо преимуществ.
Если бы вы хотели использовать select_related
, синтаксис был бы classes = Class.objects.select_related('teacher').filter(teacher=teacher)
Во-первых, самый простой способ получить все классы по каждому учителю - это использовать related_name attribute
(https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.ForeignKey.related_name).
class OnlineClass(models.Model):
teacher = models.ForeignKey(
Teacher,
on_delete=models.CASCADE,
related_name='classes'
)
# All classes of a teacher
teacher.classes.all()
При использовании select_related
к SQL-запросу Django internals добавляются новые sql-соединения. Это полезно для снижения нагрузки на движок базы данных, быстрого получения данных, и да, это только для чтения.
for obj in OnlineClass.objects.all():
# This hits the database every cycle to get the teacher data,
# with a new query like: select * from teacher_table where id = ...
print(obj.teacher)
for obj in OnlineClass.objects.select_related('teacher').all():
# This don'ts hits the database.
# Previously, the Django ORM joined the
# OnlineClass and Teacher data with a single SQL query.
print(obj.teacher)
Я думаю, что в вашем примере с одним учителем использование "select_related" или нет не имеет большого значения.