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”不会有很大的不同。
我在 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”不会有很大的不同。