Django模型中的很多功能,如何分离它?

dt0*_*xff 1 python django

我得到了带有大量子应用程序的巨大 Django 应用程序。目前,我正在一个子应用程序中重新设计模型,所以我遇到了一个......问题。我有大量分离的丑陋函数来处理模型。基本上,它类似于:

def get_some_things(...):
 def postprocess(...):
  pass
 def preprocess(...):
  pass
 preprocess(...)
 x = MyModel.objects.....get(1)
 return postprocess(x, ...)
Run Code Online (Sandbox Code Playgroud)

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

MyModel.get_some_things(...)
Run Code Online (Sandbox Code Playgroud)

或者甚至像这样:

MyModel.objects.get_some_things(...)
Run Code Online (Sandbox Code Playgroud)

但!我的函数太多了,所以我无法在model.py 中编写它。所以,我有几个想法:

  1. 创建 model_mymodel.py 并使用其中的所有函数和静态函数定义我的模型。但是......我不确定,我需要把它放在模型类中吗?
  2. 创建 mymodel_manager.py 并为 mymodel 创建模型管理器,在这里定义函数。但是......我的一些“函数”应该只返回字典、列表甚至数字。我想知道,让模型管理器能够返回除 QuerySet 之外的东西在意识形态上是错误的吗?
  3. 覆盖__getattr__的为MyModel类和类似的模块动态地加载functions_common.pyfunctions_things.py等等,店内聚集功能于字典和调用需要的?

Jes*_*ame 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
Run Code Online (Sandbox Code Playgroud)

关于你自己的建议:

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

myapp/
    models/
        __init__.py
            from mymodel import MyModel
        mymodel.py
Run Code Online (Sandbox Code Playgroud)

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

#mymodel.py
class MyModel(models.Model):
    ...
    class Meta:
        app_label = 'myapp'
Run Code Online (Sandbox Code Playgroud)

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

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