Split models.py into several files

diegueus9 picture diegueus9 · Jun 13, 2011 · Viewed 52.8k times · Source

I'm trying to split the models.py of my app into several files:

My first guess was do this:

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

This doesn't work, then i found this, but in this solution i still have a problem, when i run python manage.py sqlall app1 I got something like:

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;

I'm not pretty sure about this, but i'm worried aboout the part The following references should be added but depend on non-existent tables:

This is my model1.py file:

from django.db import models

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

This is my model3.py file:

from django.db import models

from store.models import Store

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

And apparently works but i got the comment in alter table and if I try this, same thing happens:

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

So, should I run the alter for references manually? this may bring me problems with south?

Answer

Vic picture Vic · Jun 11, 2016

For anyone on Django 1.9, it is now supported by the framework without defining the class meta data.

https://docs.djangoproject.com/en/1.9/topics/db/models/#organizing-models-in-a-package

NOTE: For Django 2, it's still the same

The manage.py startapp command creates an application structure that includes a models.py file. If you have many models, organizing them in separate files may be useful.

To do so, create a models package. Remove models.py and create a myapp/models/ directory with an __init__.py file and the files to store your models. You must import the models in the __init__.py file.

So, in your case, for a structure like

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

You only need to do

#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

A note against importing all the classes:

Explicitly importing each model rather than using from .models import * has the advantages of not cluttering the namespace, making code more readable, and keeping code analysis tools useful.