将models.py分割成多个文件

132 投票
6 回答
80170 浏览
提问于 2025-04-16 19:29

我想把我应用里的 models.py 文件拆分成几个小文件:

我最开始的想法是这样做:

myproject/
    settings.py
    manage.py
    urls.py
    __init__.py
    app1/
        views.py
        __init__.py
        models/
            __init__.py
            model1.py
            model2.py
    app2/
        views.py
        __init__.py
        models/
            __init__.py
            model3.py
            model4.py

但是这样不行,后来我找到了一些资料,这个链接里有个解决方案,但我在这个方案中还是遇到了问题。当我运行 python manage.py sqlall app1 时,出现了类似这样的提示:

BEGIN;
CREATE TABLE "product_product" (
    "id" serial NOT NULL PRIMARY KEY,
    "store_id" integer NOT NULL
)
;
-- The following references should be added but depend on non-existent tables:
-- ALTER TABLE "product_product" ADD CONSTRAINT "store_id_refs_id_3e117eef" FOREIGN KEY     ("store_id") REFERENCES "store_store" ("id") DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "product_product_store_id" ON "product_product" ("store_id");
COMMIT;

我不是很确定这个问题,但我担心提示中的 The following references should be added but depend on non-existent tables: 这部分。

这是我的 model1.py 文件:

from django.db import models

class Store(models.Model):
    class Meta:
        app_label = "store"

这是我的 model3.py 文件:

from django.db import models

from store.models import Store

class Product(models.Model):
    store = models.ForeignKey(Store)
    class Meta:
        app_label = "product"

看起来是可以工作的,但我在 alter table 的地方得到了一个评论,如果我尝试这个,结果也是一样:

class Product(models.Model):
    store = models.ForeignKey('store.Store')
    class Meta:
        app_label = "product"

那么,我是不是应该手动运行这个 alter 来处理引用?这样可能会给我带来 south 的问题吗?

6 个回答

13

我其实找到了一个正好和你问的问题相关的教程,你可以在这里查看:

https://web.archive.org/web/20190331105757/http://paltman.com/breaking-apart-models-in-django/

有一个关键点可能对你有帮助——你可能需要在Meta类中使用db_table字段,把重新定位的类指向它们自己的表。

我可以确认这种方法在Django 1.3中是有效的。

196

对于使用Django 1.9的朋友们,现在这个框架支持你不需要定义类的元数据了。

点击这里查看详细信息

注意:对于Django 2,情况还是一样的

使用 manage.py startapp 命令可以创建一个应用的结构,其中包括一个models.py文件。如果你的模型很多,把它们分开放在不同的文件里可能会更方便。

要做到这一点,你可以创建一个模型包。先删除models.py,然后创建一个 myapp/models/ 目录,并在里面放一个 __init__.py 文件和其他存放模型的文件。记得在 __init__.py 文件中导入这些模型。

所以,在你的情况下,如果结构是这样的:

app1/
    views.py
    __init__.py
    models/
        __init__.py
        model1.py
        model2.py
app2/
    views.py
    __init__.py
    models/
        __init__.py
        model3.py
        model4.py

你只需要做:

#myproject/app1/models/__init__.py:
from .model1 import Model1
from .model2 import Model2

#myproject/app2/models/__init__.py:
from .model3 import Model3
from .model4 import Model4

关于导入所有类的一个小提示:

逐个导入每个模型,而不是使用 from .models import *,这样可以避免命名空间混乱,让代码更易读,同时也能让代码分析工具更好用。

42

我会这样做:

myproject/
    ...
    app1/
        views.py
        __init__.py
        models.py
        submodels/
            __init__.py
            model1.py
            model2.py
    app2/
        views.py
        __init__.py
        models.py
        submodels/
            __init__.py
            model3.py
            model4.py

然后

#myproject/app1/models.py:
    from submodels/model1.py import *
    from submodels/model2.py import *

#myproject/app2/models.py:
    from submodels/model3.py import *
    from submodels/model4.py import *

不过,如果你没有特别好的理由,就把model1和model2直接放在app1/models.py里,把model3和model4放在app2/models.py里。

---第二部分---

这是app1/submodels/model1.py文件:

from django.db import models
class Store(models.Model):
    class Meta:
        app_label = "store"

所以请修正你的model3.py文件:

from django.db import models
from app1.models import Store

class Product(models.Model):
    store = models.ForeignKey(Store)
    class Meta:
        app_label = "product"

编辑一下,以防以后有人遇到这个问题:可以看看django-schedule,这是一个做类似事情的项目示例。

https://github.com/thauber/django-schedule/tree/master/schedule/models https://github.com/thauber/django-schedule/

撰写回答