Models.py становится огромным, что является лучшим способом разбить его?

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

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

Итак, есть простой способ просто использовать? В PHP-говорить я хотел бы предложить супервизору, что у нас есть models.py include() классы моделей из других мест. Понятно, что это позволило бы моделям иметь всю логику, которую мы хотим, но уменьшаем размер файла за счет увеличения количества файлов (что приводит к меньшим проблемам управления версиями, таким как конфликты и т.д.).

Итак, есть ли простой способ удалить классы моделей из файла models.py, но все же модели работают со всеми инструментами Django? Или, есть ли совершенно другое, но элегантное решение общей проблемы "большого" файла models.py? Любой вход будет оценен.

Ответ 1

Django предназначен для создания множества небольших приложений вместо одного большого приложения.

В каждом большом приложении много небольших приложений, которые пытаются освободиться.

Если ваш models.py чувствует себя большим, вы делаете слишком много. Стоп. Расслабьтесь. Раскладываем.

Найдите меньшие, потенциально многоразовые компоненты приложения или части. Вам не нужно их повторно использовать. Просто подумайте о них как о потенциально многоразовом.

Рассмотрите свои пути обновления и разложите приложения, которые вы, возможно, захотите заменить в какой-то день. Вам не нужно их заменять, но вы можете рассматривать их как самостоятельный "модуль" программирования, который в будущем может быть заменен чем-то более прохладным.

У нас около десятка приложений, каждая model.py составляет не более 400 строк кода. Все они довольно сосредоточены на менее чем полудюжине дискретных определений классов. (Это не жесткие ограничения, это наблюдения нашего кода.)

Мы разлагаемся рано и часто.

Ответ 2

Естественно, что классы моделей содержат методы работы с моделью. Если у меня есть модель книги с методом book.get_noun_count(), там, где она принадлежит - я не хочу писать "get_noun_count(book)", если только метод по сути не принадлежит другому пакету. (Может быть, например, если у меня есть пакет для доступа к API Amazon с "get_amazon_product_id(book)".)

Я сжался, когда в документации Django было предложено разместить модели в одном файле, и я взял несколько минут с самого начала, чтобы выяснить, как разбить его на правильный подпакет.

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

__init__.py выглядит следующим образом:

from .book import Book

поэтому я все еще могу написать "из книги импорта сайтов .models".


Для версий до Django 1.7 требуется только следующее: https://code.djangoproject.com/ticket/3591

Единственный трюк в том, что вам нужно явно установить каждое приложение модели из-за ошибки в Django: предполагается, что имя приложения является третьей до последней записью в пути к модели. "site.models.Book" приводит к "сайту", что является правильным; "site.models.book.Book" заставляет думать, что имя приложения - "модели". Это довольно неприятный хак на части Django; он должен, вероятно, искать список установленных приложений для соответствия префикса.

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

Возможно, вы могли бы использовать базовый класс или метакласс для его обобщения, но я еще не потрудился с этим.

Ответ 3

Я не могу решить, какую из многих возможных проблем вы можете иметь. Вот несколько вариантов ответов:

  • несколько моделей в одном файле

    Поместите их в отдельные файлы. Если есть зависимости, используйте импорт, чтобы втянуть дополнительные модели.

  • посторонние логические/служебные функции в models.py

    Поместите дополнительную логику в отдельные файлы.

  • статические методы для выбора некоторых экземпляров модели из базы данных

    Создайте новый Manager в отдельном файле.

  • очевидно, связанные с моделью

    save, __unicode__ и get_absolute_url являются примерами.