繁体   English   中英

将“普通” Python类集成到Django模型类中

[英]Integration of 'normal' Python class into a Django models class

我编写了一个具有许多类的Python应用程序。 假设其中一个是这样的(过于简单-但我尝试表示功能的类型):

class PythonXyz(object):

    def __init__(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save(self, filename):
        #some code that saves data to disk

    def load(self, filename):
        #some code that loads data from disk

当该应用程序正常运行但缺乏可用性时,我决定放弃该应用程序,以便可以将浏览器用作穷人的GUI,也可以使用数据库优势。 所以我像这样制作了一个model.py:

class DjangoXyzModel(models.model):
    x = models.FloatField()
    y = models.FloatField()

然后,我修改了PythonXYZ类中的load()和save()方法以使用数据库而不是文件,并通过浏览器创建了一些视图。

现在,我得到了3个Django应用程序,[edit]具有不同的数据库模式[/ edit],每个应用程序都有其自己的models.py文件,其中包含多个模型类,此外,我的原始代码还位于单独的文件夹中。 我觉得这一切都变得很混乱,并让我想到将所有PythonXyz方法完全集成到DjangoXyzModel类中的设计要简洁得多,例如:

class DjangoXyzModel(models.model):
    x_db = models.FloatField()
    y_db = models.FloatField()

    def init_lists(self):
        self.x = []
        self.y = []
        self.z = []

    def append(self, x, y):
        self.x.append(x)
        self.y.append(y)

    def get_x(self):
        return self.x

    def get_y(self):
        return self.y

    def get_z(self):
        return self.x + self.y

    def size(self):
        return len(self.x)

    def dump(self):
        #generate some output

    def do_some_complex_stuff(self, q):
        #lots of calculations and manipulation of the self.x and self.y lists.

    def save_to_db(self):
        #some code that saves x,y lists to the database

    def load_from_db(self, filename):
        #some code that loads x,y lists from the database

我的问题是 :这种方法会被认为是Django模型类的“污染”,还是可以,只是个人喜好,还是这可能正是应该使用模型类的方式? 如果不建议或不赞成这样做,哪种更好的方法来处理重复的类?

请注意,明显的(?)解决方案完全摆脱列表并直接从数据库工作是不可接受的,因为我需要将列表保存在内存中以便更快地访问。 例如,列表一次从数据库加载到内存中,并被访问了数百或数千次。 每个列表可能大于1000个项目,因此,当需要一个值时(通常不是连续的),批量读/写也比单独访问要快得多。 此外,在最终将数据提交到数据库之前,通常会对其进行多次修改。

听起来您不应该将PythonXYZ类与Django模型集成。 让Django管理数据库(包含单独的xy FloatField记录)。 您的代码处理实际上在管理Model实例集合的列表逻辑。 在Model上具有旨在在该个别Model实例的范围之外的东西上运行的方法是没有意义的。 您可能需要一个分为两部分的解决方案-具有Collection类的Manager

为您的列表级加载/保存逻辑编写一个自定义管理器 这比纯粹的泛型类要好,因为它在概念上将列表操作与它们正在操作的数据库记录联系在一起。 Manager将处理将Model实例的初始加载到这些x / y / z列表中,并将该列表保存回数据库中。 从文档中:

添加额外的Manager方法是向模型添加“表级”功能的首选方法。 (对于“行级”功能-即作用于模型对象的单个实例的功能-使用模型方法,而不是自定义Manager方法。)

自定义Manager方法可以返回您想要的任何内容。 它不必返回QuerySet。

由于列表本身听起来像实体,因此您可能需要一个Collection类,该类为列表提供do_some_complex_stuff(),size(),dump()等方法。 这是您现在拥有的PythonXyz对象。 您可能可以对list进行子类化,以避免重新实现append()等。 Manager的load()可以返回此Collection类,而其save()会将Collection转换为Model实例,以进行数据库写入。

至于在三个应用程序之间共享通用代码。

  • 您可以使用抽象模型来保存包含具体应用程序模型的通用代码。
  • 如果您需要在架构级别访问通用性,请不要使用抽象的父模型。 (然后,您将有一个基表和单个表,其中仅包含特定于应用程序的列。)
  • 仅当您想要不同的行为并且架构相同/共享时,才使用代理模型。

将所有PythonXyz方法完全集成到DjangoXyzModel类中

别。 将基类分开,然后创建使用MI组合它们的模型代理 ,并在适当的地方覆盖行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM