1

我得到了带有大量子应用程序的巨大 Django 应用程序。目前,我正在一个子应用程序中重新设计模型,所以我遇到了一个......问题。我有大量分离的丑陋功能可用于模型。基本上,它有点像:

def get_some_things(...):
 def postprocess(...):
  pass
 def preprocess(...):
  pass
 preprocess(...)
 x = MyModel.objects.....get(1)
 return postprocess(x, ...)

而且我有很多这样的功能,真的很丑!在当前代码中使用它很丑陋(如DatabaseAccessor.get_db().django_kitty().get_some_things(...))。所以,我的想法是让开发人员能够像这样使用这些功能:

MyModel.get_some_things(...)

甚至像这样:

MyModel.objects.get_some_things(...)

但!我有太多的功能,所以我不能在model.py中写它。所以,我有几个想法:

  1. 创建 model_mymodel.py 并使用其中的所有函数和静态函数定义我的模型。但是......我不确定,我需要把它放在模型课上吗?
  2. 创建 mymodel_manager.py 并为 mymodel 创建模型管理器,在此处定义函数。但是......我的一些“函数”应该只返回字典、列表甚至数字。我想知道,让模型管理器能够返回除 QuerySet 之外的东西在意识形态上是错误的吗?
  3. 重写__getattr__MyModel 类并动态加载模块等functions_common.pyfunctions_things.py将收集的函数存储到字典中并需要调用?
4

3 回答 3

5

如果您的模型需要许多独特的方法,那么拥有庞大的模型定义就是您要付出的代价。如果出于某种原因您确实想将功能拆分到其他文件(或者,对于一些实际有用的东西,共享通用功能),您可以使用 mixin 方法:

#mymodel.py
class MyModelMixin:
    def django_kitty(self, ...):
        pass
    def postprocess(self, ...):
        pass
    def preprocess(self, ...):
        pass

#models.py
from mymodel import MyModelMixin

class MyModel(models.Model, MyModelMixin):
    pass

关于你自己的建议:

1 - 如果您想要每个模型单独的文件,您可以使用这种方法:

myapp/
    models/
        __init__.py
            from mymodel import MyModel
        mymodel.py

请注意,您需要为每个模型显式设置 app_label:

#mymodel.py
class MyModel(models.Model):
    ...
    class Meta:
        app_label = 'myapp'

2 - 管理器方法的返回值类型无关紧要。管理器和模型的区别点是分别将级功能分开。

3 - 听起来像是不必要的魔法,压倒一切Model.__getattr__是一项痛苦的任务。

于 2012-12-16T20:24:29.650 回答
1

听起来选项2是要走的路。

模型管理器方法不返回 QuerySet没有任何问题。

于 2012-12-16T20:21:39.207 回答
0

我用于模型函数与模型管理器的指导原则是:只要目标是作用于单个模型对象,我就会定期在模型上使用方法函数。但是,如果我的用例需要我处理模型的多个对象并满足我的 DRY 激励,我会为此使用模型管理器。

于 2015-02-05T17:30:40.430 回答