select_related 在 django 中的简单查询中的使用

Use of select_related in simple query in django

我在 Django 中有一个模型,其中一个字段与教师模型有 fk 关系。我在 django 中遇到了 select_related 并想在我看来使用它。但是,我不确定是否要在我的查询中使用它。

我的模特:

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)

我已经评论了问题的行或部分。所以我想列出那个老师的所有类。在这里我使用了过滤器。但是我们可以在这里使用 select_related 吗?我的理解是,如果我还想显示教师模型的其他字段,例如姓名或 college_name,那么我必须使用它。否则我的做法是正确的。另外,select_related 只用于 get api 而不是 post api,是这样吗??

select_related用于在执行查询时select来自相关对象的附加数据。它会导致更复杂的查询。但如果您必须访问相关数据,它会提高性能,因为不需要额外的数据库查询。

参见文档 here

在您的代码中可以使用 select_related,但效率很低,因为您没有访问所查询 类 的相关对象。因此,使用 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 内部 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”不会有很大的不同。