Django - 优化问题

时间:2010-11-27 03:21:10

标签: django optimization query-optimization

如果你有一些模特:

class Teacher(models.Model):
    name = models.CharField(max_length=50)

class Student(models.Model):
    age = models.PositiveIntegerField()
    teacher = models.ForeignKey(Teacher, related_name='students')

你可以这样使用它:

>>> student = Student.objects.get(pk=1)
>>> student.teacher.name  # This hits the database
'Some Teacher'
>>> student.teacher.name  # This doesn't (``teacher`` is cached on the object)
'Some Teacher'

那真棒。 Django缓存相关对象,以便您可以再次使用它而不必滥用您的数据库。

但是,如果你这样使用它:

>>> teacher = Teacher.objects.get(pk=1)
>>> for student in teacher.students.all():  # This hits the database
...     print(student.age)
... 
8
6
>>> for student in teacher.students.all():  # This does too (obviously)
...     print(student.age)
... 
8
6

此方向没有缓存或高效访问相关对象。

我的问题是:是否有内置(或无问题的方式)以有效的方式(缓存方式)向后访问相关对象,就像在{{{ 1}}上面的例子?

我想要这个的原因是因为我有一个模型有多个方法需要反复访问相同的相关对象,所以一个应该有12个查询的页面最终会有大约30个。

3 个答案:

答案 0 :(得分:2)

没有任何内置方式。我已经写过关于这个问题的on my blog,其中介绍了一种优化访问反向关系的技术。

答案 1 :(得分:1)

orokusaki,

您只需将查询集缓存为python变量

students = teacher.students.all()

然后在你的for循环中使用学生。

以下是Django自己关于此特定问题的文档的链接: - )

http://docs.djangoproject.com/en/1.1/topics/db/optimization/#understand-cached-attributes

答案 2 :(得分:0)

也许尝试一下?

teacher = Teacher.objects.select_related().get(pk=1)

http://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.QuerySet.select_related

我从来没有在结果上使用select_related和.all(),所以我不确定它是否会节省DB。