Использование 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" или нет не имеет большого значения.

Вернуться на верх