Django: подсказки для новичков
Я изучаю Django несколько месяцев и делаю на нём свой второй проект (первый — этот сайт). Помимо того, что занимаюсь собственно проектом, я читаю статьи и книги об этом фреймворке и время от времени ищу ответы на StackExchange. Пожалуй, чтобы не забыть найденное, лучше записать это в блог.
1. Настраивайте виртуальное окружение и проект заранее.
Когда я смотрю обучающие ролики на YouTube, мне бросается в глаза, что инструкторы часто натыкаются на ошибки — а именно, забывают добавить приложение в раздел “INSTALLED APPS” в файле settings.py. На мой взгляд, хотя это довольно нудно, лучше сесть и настроить всё сразу — сделать виртуальное окружение под проект, прописать название приложения в settings.py и там же задать адреса папок (static, media и т.д.) и urls. И тут же создать superuser — вам всё равно скоро понадобится лазать в админку.
2. Импортируем правильно.
Про импорты я вычитала сразу три лайфхака. Во-первых, авторы Two Scoops of Django советуют при импорте придерживаться конвенций PEP 8, импортируя модули в следующем порядке:
- стандартные библиотеки Python
- модули ядра Django
- импорт сторонних приложений, в том числе, тех, что не связаны с Django напрямую
- импорт из ваших собственных приложений, созданных на Django (например, models.py вашего блога)
Таким образом, код будет выглядеть примерно так:
#импорт стандартной бибилиотеки
from math import sqrt
#импорт из ядра Django
from django.db import models
from django.utils.translation import ugettext_lazy
#импорт из сторонних приложений
from django_extensions.db.models import TimeStampedModel
#импорт из ваших собственных приложений
from split.models import BananaSplit
Ещё одно правило — использовать «относительный импорт» (relative imports) в тех случаях, когда вы импортируете модули, находящиеся в той же папке. Например, у вас есть приложение blog, а внутри — models, views и другое стандартное добро. Внутри ваших views вам нет нужды писать
from blog.models import Post, Comment
лучше написать просто
from .models import Post, Comment
Таким образом, мы не пишем название папки, а ставим точку и после неё название файла. Если мы поменяем название приложения или изменится что-то ещё, нам не придётся переписывать названия папок вручную.
Кроме того, важно помнить, что иногда в Django попадаются классы с одинаковыми именами (а что делать? проект большой) — например, CharField есть и в django.db.models, и в django.forms. Если нам нужны оба таких класса, лучше воспользоваться (довольно стандартным, честно говоря) трюком import as:
from django.db.models import CharField as ModelCharfield
from django.forms import CharField as FormCharfield
3. Забудьте про функцию url()
Создатели Django не рекомендуют использовать url(), прописывая пути в urls.py. Эта функция устарела и, скорее всего, в будущих версиях её упразднят. Чтобы было понятнее, раньше адреса прописывали так:
url(r'^$', views.index, name="index")
Теперь есть функция с более простым и понятным синтаксисом — path(). Пример:
path('blog/', views.page)
path() не поддерживает регулярные выражения, так что если вы попытаетесь впихнуть их в эту функцию, они работать не будут. Но на этот случай есть re_path() — он работает практически как привычный url(). Пример (правда, если вы не знакомы с регулярными выражениями, он будет выглядеть жутко):
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive)
4. Пользуйтесь инструментами визуализации таблиц в базах данных
Вероятно, вы уже знаете, что все модели, который вы описываете в models.py — это своеобразные таблицы, хранящиеся в базе данных. В её столбцах как раз и лежат описанные вами атрибуты. Чтобы лучше понимать, как это работает и проектировать сложные системы, полезно почитать теорию баз данных. Но даже если вы её читали, представить всю машинерию мысленно может быть непросто, особенно если у вас проблемы с визуальным воображением, как у меня. На этот случай есть прекрасный инструмент SQLite Viewer. Вы кидаете в него файл с базой данных, а он показывает вам структуру таблиц и то, где НА САМОМ ДЕЛЕ находятся атрибуты, которые вам нужны.
5. Настраивайте внешний вид форм под себя
В Django есть чудесный класс, который позволяет создавать формы по моделям (“create forms form models” говорят в официальных доках, и у меня не получается выразить это лучше). Наверное, все знают, что при создании инстанса класса можно указать, какие именно поля нам нужны в классе Meta:
class Meta:
model = Game
fields = ['title', 'platforms']
Но возможно, вы не знали, что у каждого такого поля есть «widget по умолчанию», который отвечает за его отображение в форме. И он тоже настраивается в классе Meta. Допустим, у нас есть поле «многое ко многим» ManyToMany. У него стандартный виджет — SelectMultiple. Вот, например, так в моём проекте пользователь может выбрать, на каких платформах он хочет поиграть в видеоигру. В «голом» варианте без CSS это выглядит некрасиво:
Но при необходимости виджет можно поменять. Например, мы можем сделать так, что юзеру придётся выбирать только одну платформу:
class Meta:
model = Game
fields = ['title', 'platforms']
widgets = {
'platforms': Select
}
На веб-странице это будет выглядеть так:
6. В шаблонах всегда обозначайте, какие теги закрываете
В Django есть собственный язык шаблонов, который позволяет размечать структуру веб-страниц. Наверняка вы использовали {% block content %} или {% block title %}. Формально тег можно закрыть, просто написав {% endblock %}. Например, так:
{% block content %}
Какое-то содержимое
{% endblock %}
Но если у вас несколько таких блоков, а между ними ещё и HTML, вам будет очень неудобно разбираться в том, какой тег и где вы закрыли. Поэтому в закрывающих тегах лучше сразу указывать, что именно они закрывают:
{% block content %}
Много текста и html
{% endblock content %}