Разделить models.py на несколько файлов - PullRequest
70 голосов
/ 14 июня 2011

Я пытаюсь разделить 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 для ссылок вручную?это может вызвать у меня проблемы с югом?

Ответы [ 4 ]

107 голосов
/ 11 июня 2016

Для всех, кто работает с 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 * имеет преимущества, заключающиеся в том, чтобы не загромождать пространство имен, делать код более читабельным и сохранять инструменты анализа кодаполезно.

24 голосов
/ 14 июня 2011

Я бы сделал следующее:

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/

11 голосов
/ 31 июля 2011

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

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

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

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

1 голос
/ 02 февраля 2019

Легких шагов:

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

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

Для вашего: из имя_приложения .моделей. имя_файла_одели импорт имя_класса_кв_файлов_ин_модели_файлов


__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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...