Django Model中有很多功能,分开它的方式?

时间:2012-12-16 19:54:35

标签: python django

我使用大量的子应用程序获得了巨大的Django App。目前,我正在努力在一个子应用程序中重新处理模型,所以我遇到了......问题。 我有大量分离的丑陋功能来处理模型。基本上,这是一个像:

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创建模型管理器,在此处定义函数。但是......我的一些“功能”应该只返回dicts,列表甚至数字。我想知道,让模型管理器能够返回除QuerySet之外的其他东西在意识形态上是错误的吗?
  3. 覆盖MyModel类的__getattr__并动态加载functions_common.pyfunctions_things.py等模块,将收集的函数存储到字典中并调用所需的内容?

3 个答案:

答案 0 :(得分:4)

如果您的模型需要许多独特的方法,那么拥有巨大的模型定义就是您支付的价格。如果由于某种原因你确实希望将功能拆分为其他文件(或者,对于实际有用的东西,分享常用功能),你可以使用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__是一项痛苦的任务。

答案 1 :(得分:1)

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

model manager method not returning a QuerySet没有任何问题。

答案 2 :(得分:0)

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