> Обо мне Блог Портфолио
11 сентября 2018 г. 18:40

Django: подсказки для новичков

Я изучаю Django несколько месяцев и делаю на нём свой второй проект (первый — этот сайт). Помимо того, что занимаюсь собственно проектом, я читаю статьи и книги об этом фреймворке и время от времени ищу ответы на StackExchange. Пожалуй, чтобы не забыть найденное, лучше записать это в блог.

1. Настраивайте виртуальное окружение и проект заранее.

Когда я смотрю обучающие ролики на YouTube, мне бросается в глаза, что инструкторы часто натыкаются на ошибки — а именно, забывают добавить приложение в раздел “INSTALLED APPS” в файле settings.py. На мой взгляд, хотя это довольно нудно, лучше сесть и настроить всё сразу — сделать виртуальное окружение под проект, прописать название приложения в settings.py и там же задать адреса папок (static, media и т.д.) и urls. И тут же создать superuser — вам всё равно скоро понадобится лазать в админку.

2. Импортируем правильно.

Про импорты я вычитала сразу три лайфхака. Во-первых, авторы Two Scoops of Django советуют при импорте придерживаться конвенций PEP 8, импортируя модули в следующем порядке:

Таким образом, код будет выглядеть примерно так:

#импорт стандартной бибилиотеки
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 %}