Изобретая велосипед

Django обладает множеством готовых инструментов из коробки и огромным количеством готовых сторонних библиотек. Если у вас возникла проблема, то перед тем, как приступить к ее решению, попробуйте «погуглить» ее, потому что, скорее всего, решение уже было найдено до вас.

Для поиска также можно использовать онлайн-каталог Django Projects, где под категорией «apps» (компоненты, используемые для создания проектов) уже насчитывается более 3200 готовых приложений. 

Монолитная структура приложения

Несмотря на то, что на Django возможно вести разработку разными способами, опытные разработчики рекомендуют придерживаться стандартных приемов, речь о которых пойдет ниже.

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

Приложения Django могут содержать модули Python, Django модули (представления, URL-адреса, модели, формы и т.д), статические файлы, миграции баз данных, команды управления, модульные тесты и другое. Для начала вы должны разделить ваш проект на небольшие, многократно используемые приложения с помощью простой логики. 

\ecommerce_project      <= This is your Django project
    \cart               <= This is a Django cart app
    \checkout           <= This is a Django checkout app
    \products           <= This is a Django products app
    manage.py           <= Django project management utility

Подобная структура поможет вам и вашей команде быстрее разобраться в проекте, увидеть его общую картину. Кроме того, вы можете экспортировать приложения в другой проект и переиспользовать их снова или при необходимости опубликовать их на PyPi как модуль с открытым исходным кодом.

Толстые представления и тонкие модели

Фреймворк Django реализует архитектурный паттерн Model-View-Template (Модель-Представление-Шаблон), или сокращенно МVT. Вышеуказанный паттерн является модификацией распространенного в веб-программировании паттерна MVC (Модель-Представление-Контроллер)

Модель. Включает в себя запросы к базе данных, которые передают результаты в представления и шаблоны. Модели определяются в файле models.py, который находится в каталоге приложений. 

Представление. Состоит из кода, который работает с взаимодействием с пользователями, например, отправка формы посетителем сайта, обработка результатов голосования, формирование результатов из базы данных в соответствии с вашим шаблоном и прочее. Код должен находиться в файле views.py вашего приложения.

Если вы не пишете логику приложения в моделях и не используете представления, то это значит, что вы написали свой код в модели, основанный на представлении. Это делает представления «толстыми», а модель «тонкой». Однако, модели должны быть «толстыми», а представления «тонкими».   

Ко всему прочему, для достижения целей вы можете использовать пользовательские менеджеры (Custom managers). Например, пользовательский менеджер может предоставить метод with_counts(), который возвращает список всех OpinionPoll объектов, каждый с дополнительным атрибутом num_responses, и является результатом агрегированного запроса. Вы можете узнать больше, посмотрев встроенный UserManager.

Слишком много запросов на представление или неоптимизированные запросы

Механизм объектно-ориентированного отображения Django (ORM) часто обвиняют в том, что он делает слишком много запросов или делает неоптимизированые запросы. Но то же самое может происходит с ORM и в других фреймворках. 

Реальная проблема заключается в том, что часто мы не знаем о проблемах производительности и источниках их возникновения.

Одним из прекрасных инструментов отладки является Django-debug-toolbar. Эта библиотека поможет вам быстро отыскать источник проблемы. Библиотеку можно использовать для отслеживания проблем в SQL-запросах, шаблонах, кэше и пр. 

После выявления причин возникших проблем с производительностью, можно выбрать правильный путь для их устранения. Среди прочих путей решения, можно предпринять следующие шаги:

  • Настроить простые ORM-запросы (внимание на предварительную выборку);
  • Настроить и оптимизировать запросы ORM;
  • Добавить кеширование там, где это необходимо;
  • Предоставить большее количество ресурсов.

Избыточные поля модели

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

Например, половина записей модели Vehicles будет иметь s_motorcycle == True and wheel_count == 4, и вы не можете быть уверены, какому полю доверять (подсказка: ни одному). С Django вы можете рефакторить такие противоречащие свойства с помощью декоратора @property. Однако, даже если ORM позволяет обращаться к столбцам как к свойствам, обратное неверно, то есть необходимо вручную рефакторить каждый запрос.

Отсутствие индексов в моделях

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

Как правило, индекс необходим там, где вы будете использовать фильтрацию и присоединение. Пересмотрите свои QuerySets, чтобы определить, где необходимо использовать индекс. 

Непоследовательная проверка данных

Модели Django могут быть связаны с одной или несколькими формами, которые используются для создания и обновления экземпляров модели. Этим формам свойственно много действий по-умолчанию, в том числе — валидация данных, которая контролируется свойствами модели.

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

Итог

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