代码之家  ›  专栏  ›  技术社区  ›  orokusaki

Django-优化问题

  •  1
  • orokusaki  · 技术社区  · 14 年前

    如果您有一些型号:

    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
    

    这个方向没有缓存或对相关对象的有效访问。

    我的问题是: 是否有一种内置(或无问题的方法)以高效的方式(缓存方式)向后访问相关对象,就像在 student.teacher 上面的例子?

    我之所以希望这样做,是因为我有一个模型,它有多个方法需要多次访问同一个相关对象,所以一个应该有12个查询的页面最终得到大约30个。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Daniel Roseman    14 年前

    没有任何内置方式。我写过这个问题 on my blog 以优化访问反向关系的技术。

        2
  •  1
  •   Seaux    14 年前

    大阪,

    只需将查询集缓存为python变量即可。

    students = teacher.students.all()
    

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

    下面是Django自己关于这个特定问题的文档的链接:—)

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

        3
  •  0
  •   jMyles    14 年前

    试试这个吧?

    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节省。