python models.py 变得很大,分解它的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1160579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:37:00  来源:igfitidea点击:

models.py getting huge, what is the best way to break it up?

pythondjangodjango-modelsmodels

提问by Eddified

Directions from my supervisor: "I want to avoid putting any logic in the models.py. From here on out, let's use that as only classes for accessing the database, and keep all logic in external classes that use the models classes, or wrap them."

来自我的主管的指示:“我想避免在models.py. 中放置任何逻辑。从现在开始,让我们仅将其用作访问数据库的类,并将所有逻辑保留在使用模型类的外部类中,或将它们包装起来。”

I feel like this is the wrong way to go. I feel that keeping logic out of the models just to keep the file small is a bad idea. If the logic is best in the model, that's where it really should go regardless of file size.

我觉得这是错误的方式。我觉得将逻辑排除在模型之外只是为了保持文件小是一个坏主意。如果模型中的逻辑是最好的,那么无论文件大小如何,这就是它真正应该去的地方。

So is there a simple way to just use includes? In PHP-speak, I'd like to propose to the supervisor that we just have models.pyinclude() the model classes from other places. Conceptually, this would allow the models to have all the logic we want, yet keep file size down via increasing the number of files (which leads to less revision control problems like conflicts, etc.).

那么有没有一种简单的方法来使用包含?用 PHP 的话说,我想向主管建议我们只models.py包含()来自其他地方的模型类。从概念上讲,这将允许模型具有我们想要的所有逻辑,同时通过增加文件数量来减小文件大小(这会导致更少的版本控制问题,如冲突等)。

So, is there a simple way to remove model classes from the models.py file, but still have the models work with all of the Django tools? Or, is there a completely different yet elegant solution to the general problem of a "large" models.py file? Any input would be appreciated.

那么,是否有一种简单的方法可以从 models.py 文件中删除模型类,但仍然可以让模型与所有 Django 工具一起使用?或者,对于“大”models.py 文件的一般问题,是否有一个完全不同但优雅的解决方案?任何输入将不胜感激。

采纳答案by S.Lott

Django is designed to let you build many small applications instead of one big application.

Django 旨在让您构建许多小应用程序,而不是一个大应用程序。

Inside every large application are many small applications struggling to be free.

在每个大型应用程序中,都有许多努力争取自由的小型应用程序。

If your models.pyfeels big, you're doing too much. Stop. Relax. Decompose.

如果你models.py觉得自己很大,那你就做得太多了。停止。放松。分解。

Find smaller, potentially reusable small application components, or pieces. You don't have to actuallyreuse them. Just think about them as potentially reusable.

查找较小的、可能可重用的小型应用程序组件或部分。您不必实际重用它们。只需将它们视为可能可重用即可。

Consider your upgrade paths and decompose applications that you might want to replace some day. You don't have to actuallyreplace them, but you can consider them as a stand-alone "module" of programming that might get replaced with something cooler in the future.

考虑您的升级路径并分解您有一天可能想要替换的应用程序。您不必实际更换它们,但您可以将它们视为独立的编程“模块”,将来可能会被更酷的东西所取代。

We have about a dozen applications, each model.pyis no more than about 400 lines of code. They're all pretty focused on less than about half-dozen discrete class definitions. (These aren't hard limits, they're observations about our code.)

我们有大约十几个应用程序,每个应用程序model.py不超过 400 行代码。他们都非常专注于不到六个离散类定义。(这些不是硬性限制,它们是对我们代码的观察。)

We decompose early and often.

我们很早就分解了,而且经常分解。

回答by Glenn Maynard

It's natural for model classes to contain methods to operate on the model. If I have a Book model, with a method book.get_noun_count(), that's where it belongs--I don't want to have to write "get_noun_count(book)", unless the method actually intrinsically belongs with some other package. (It might--for example, if I have a package for accessing Amazon's API with "get_amazon_product_id(book)".)

模型类很自然地包含对模型进行操作的方法。如果我有一个带有方法的 Book 模型,book.get_noun_count()那就是它所属的地方——我不想写“ get_noun_count(book)”,除非该方法实际上本质上属于某个其他包。(它可能——例如,如果我有一个使用“ get_amazon_product_id(book)”访问亚马逊 API 的包。)

I cringed when Django's documentation suggested putting models in a single file, and I took a few minutes from the very beginning to figure out how to split it into a proper subpackage.

当 Django 的文档建议将模型放在单个文件中时,我感到很害怕,从一开始我就花了几分钟的时间来弄清楚如何将其拆分为适当的子包。

site/models/__init__.py
site/models/book.py

__init__.pylooks like:

__init__.py好像:

from .book import Book

so I can still write "from site.models import Book".

所以我仍然可以写“from site.models import Book”。



The following is only required for versions prior to Django 1.7, see https://code.djangoproject.com/ticket/3591

以下仅适用于 Django 1.7 之前的版本,参见 https://code.djangoproject.com/ticket/3591

The only trick is that you need to explicitly set each model's application, due to a bug in Django: it assumes that the application name is the third-to-last entry in the model path. "site.models.Book" results in "site", which is correct; "site.models.book.Book" makes it think the application name is "models". This is a pretty nasty hack on Django's part; it should probably search the list of installed applications for a prefix match.

唯一的技巧是您需要显式设置每个模型的应用程序,这是由于 Django 中的一个错误:它假定应用程序名称是模型路径中的倒数第三个条目。“site.models.Book”结果为“site”,这是正确的;“site.models.book.Book”使它认为应用程序名称是“models”。对 Django 来说,这是一个非常讨厌的 hack;它可能应该在已安装的应用程序列表中搜索前缀匹配。

class Book(models.Model):
    class Meta: app_label = "site"

You could probably use a base class or metaclass to generalize this, but I haven't bothered with that yet.

您可能可以使用基类或元类来概括这一点,但我还没有为此烦恼。

回答by hughdbrown

I can't quite get which of many possible problems you might have. Here are some possibilities with answers:

我不太清楚您可能遇到的许多问题中的哪一个。以下是一些可能的答案:

  • multiple models in the same file

    Put them into separate files. If there are dependencies, use import to pull in the additional models.

  • extraneous logic / utility functions in models.py

    Put the extra logic into separate files.

  • static methods for selecting some model instances from database

    Create a new Managerin a separate file.

  • methods obviously related to the model

    save, __unicode__ and get_absolute_url are examples.

  • 同一文件中的多个模型

    将它们放入单独的文件中。如果存在依赖关系,请使用 import 拉入其他模型。

  • models.py 中的无关逻辑/实用功能

    将额外的逻辑放入单独的文件中。

  • 从数据库中选择一些模型实例的静态方法

    在单独的文件中创建一个新的管理器

  • 与模型明显相关的方法

    save, __unicode__ 和 get_absolute_url 是例子。