Сплит models.py в несколько файлов

Я пытаюсь разбить 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"

Итак, нужно ли вручную запускать ссылку на ссылки? это может вызвать проблемы с югом?

Ответ 1

Я даже не могу представить, почему вы хотите это сделать. Но я предполагаю, что у тебя есть веская причина. Если мне нужно было это сделать по какой-то причине, я бы сделал следующее:

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:

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/

Ответ 2

Для всех, кто использует Django 1.9, он теперь поддерживается платформой без определения метаданных класса.

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

ПРИМЕЧАНИЕ: для 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 * имеет преимущества, заключающиеся в том, чтобы не загромождать пространство имен, делать код более читабельным и сохранять полезными инструменты анализа кода.

Ответ 3

На самом деле я натолкнулся на учебное пособие, о котором вы спрашиваете, вы можете просмотреть его здесь:

http://paltman.com/breaking-apart-models-in-django/

Один из ключевых моментов, который, вероятно, имеет значение - вы можете использовать поле db_table в классе Meta, чтобы переместить перемещенные классы обратно в их собственную таблицу.

Я могу подтвердить, что этот подход работает в Django 1.3

Ответ 4

Легкие шаги:

  1. Создайте папку модели в вашем приложении (имя папки должно быть моделью)
  2. Удалить файл model.py из каталога приложения ( сделайте резервную копию файла, пока вы его удаляете)
  3. И после создания файла инициализации.py в папке модели
  4. А после инициализации.py файла пишется простая строка
  5. И после создания файла модели в папке вашей модели имя файла модели должно совпадать с именем класса, если имя класса "Сотрудник", чем имя файла модели должно быть похоже на "employee.py"
  6. И после того, как в файле модели определите вашу таблицу базы данных так же, как и в файле model.py
  7. Сохрани это

Мой код: от django_adminlte.models.employee import Employee

Для вашего: от app_name.models. имя_файла_файла_только импортировать имя_класса_который_дефин_ин_модель_файл


__init__.py

from django_adminlte.models.employee import Employee

model/employee.py (employee is separate model file)

from django.db import models

class Employee(models.Model):
eid = models.CharField(max_length=20)
ename = models.CharField(max_length=20)
eemail = models.EmailField()
econtact = models.CharField(max_length=15)

class Meta:
    db_table = "employee"
    # app_label = 'django_adminlte'

def __str__(self):
    return self.ename