大佬教程收集整理的这篇文章主要介绍了当您无法使用 select_related 时,如何避免 Django 中的 n+1 查询?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
这是我经常遇到的问题。假设我有三个模型:
class CourseType(models.Model):
name = models.CharFIEld(max_length=50)
class CourseLevel(models.Model):
name = models.CharFIEld(max_length=50)
course_type = models.ForeignKey(CourseType,on_delete=models.CASCADE)
class Course(models.Model):
name = models.CharFIEld(max_length=50)
course_level = models.ForeignKey(CourseLevel,on_delete=models.CASCADE)
def __str__(self):
return "{}-{}: {}".format(self.course_level.course_type.name,self.course_level.name,self.name)
如果我要迭代 Course.objects.all()
并打印 Course
对象,那将是一个 n+1 查询。这可以通过使用 select_related
:
Course.objects.select_related('course_level','course_level__course_type')
问题在于我必须记住每次都使用 select_related
。它也很丑,特别是如果你有另一个模型,比如 CourseDetails
。
对此的一种解决方案是使用自定义管理器:
class CourseManager(models.Manager):
def with_names(self):
return self.select_related('course_level','course_level__course_type')
然后我可以使用 Course.with_names.all()
并且不再需要每次都添加 select_related
。这有一个主要限制 - 我只能在直接使用 Course
时利用管理器。很多时候我会通过外键遍历 Course
对象,而且我需要再次记住使用 select_related
并将其散布在我的代码中。一个例子:
class Student(models.Model):
name = models.CharFIEld(max_length=50)
class StudentCourseEnroll(models.Model):
student = models.ForeignKey(Student,on_delete=models.CASCADE)
course = models.ForeignKey(Course,on_delete=models.CASCADE)
现在如果我想打印出所有学生和他们注册的课程,我必须再次记住使用 select_related
并且它更丑:
StudentCourseEnroll.objects.select_related('course__course_level__course_type','course__course_level')
我可以为 StudentCourseEnroll
创建另一个经理,但这似乎违背了 DRY 原则 - 我会让多个经理做同样的事情。
有没有更好的方法来解决这个问题?有没有什么我可以直接在 Course
模型中做而不必考虑这个问题的?
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
以上是大佬教程为你收集整理的当您无法使用 select_related 时,如何避免 Django 中的 n+1 查询?全部内容,希望文章能够帮你解决当您无法使用 select_related 时,如何避免 Django 中的 n+1 查询?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。