【发布时间】:2015-05-31 02:15:22
【问题描述】:
是时候提出关于良好设计和性能的问题了。
假设我有三个 django 模型:
class Student(Model):
classroom = ForeignKey('Classroom')
# student info
class Classroom(Model):
teacher = ForeignKey('Teacher')
# classroom info
class Teacher(Model):
# teacher info
我想确保视图具有访问教师拥有的所有学生的好方法。为此,在教师模型上定义一个方法可能是有意义的
def get_students(self):
# code
现在,有几种方法可以做到这一点。我的首要任务之一是让每个模型与整体数据库模式相对不可知。因此,我不太喜欢以下解决方案:
def get_students(self):
return Student.objects.filter(classroom__teacher=self)
此解决方案依赖于学生通过课堂与教师建立联系;如果我改变这个结构(也许学生需要直接与老师联系,而不是通过教室),我现在必须改变 get_students 方法。如果我有一堆模型并且它们通过这些嵌套关系相互关联,那么更改架构意味着搜索所有此类过滤器查询。在我的特殊情况下,我有许多模型存在于不同的应用程序中,并且我的项目变得相当大,所以采用这种方法意味着所有的机会都让我错过了一些东西并创建了一个错误。即使我的测试很好,我也将不得不花费大量时间寻找查询。
一个对我来说似乎更优雅的解决方案是有一个定义 for_teacher 方法的学生管理器:
class StudentManager(Manager):
def for_teacher(self, teacher):
return self.filter(classroom__teacher=teacher)
现在,我的 get_students 方法可以如下所示:
def get_students(self):
return Students.objects.for_teacher(self)
通过这种方法,我将事物抽象化,使教师不知道它与学生的关系(即通过课堂)。它所知道的只是它与学生有某种关系。当然,如果我更改架构,我将不得不更改 StudentManager。但是,如果我再次想象一个项目具有许多通过不同模型与其他模型相关的模型,则此方法提供了一种将所有依赖于模式的调用集中在一个地方(管理器)的方法。这使我不必在各种模型(也许还有视图)中寻找查询。
问题是,这是一种理智的方法吗?如果不是,那么处理此问题的首选方法是什么?
推论:
如上所述,我的项目在一堆应用程序中有一堆模型,它们需要以某种方式相互了解。所以现在我们有一个额外的问题:如果 Teacher 包含一个 get_students 方法,而 Student 有一个 get_teacher 方法,我现在会遇到循环模块依赖关系。这个新问题的潜在解决方案是这个版本的 get_students (get_teacher):
def get_students(self):
from student.models import Student
return Student.objects.for_teacher(self)
我来自一个将导入放在程序顶部的世界,所以这对我来说似乎有点奇怪。这是一个合理的方法吗?像这样进行动态导入时是否有性能考虑? Python 是否会在 get_students 方法中缓存 Student 导入,使其只发生一次?
提前致谢!
【问题讨论】:
-
我认为你在正确的轨道上。 Check this post by Tom Christie,他知道一两件事.. ;)
-
谢谢!我快速浏览了一下,看起来那里有一些可靠的指针。我会详细阅读。
标签: python django orm django-orm