Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Latest commit

 

History

History
401 lines (253 loc) · 18.4 KB

lesson36.md

File metadata and controls

401 lines (253 loc) · 18.4 KB

Урок 36. Manage-команды. Manage-команды приложений. Кастомные manage-команды.

Manage-команды и настройки.

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

Существует три способа запуска manage-команды:

django-admin <command> [options]
python manage.py <command> [options]
python -m django <command> [options]

В случае запуска через django-admin вы можете указать, какой файл настроек использовать при помощи опции --settings.

Если вы запускаете команду через manage.py (самый распространенный способ), файл настроек будет выбран в соответствии с самим файлом manage.py (Напоминаю структуру, информация о файле настроек для Django проекта находится именно в файле manage.py).

Мы использовали некоторые команды, но давайте посмотрим подробнее.

Доступные команды.

Check

python manage.py check [app_label [app_label ...]]

Например:

django-admin check auth admin myapp

Команда для запуска проверки кода на качество (например, что неправильно указаны аргументы модели или некорректно указано свойство для класса админки и т. д., список огромный) Посмотреть базовый список проверок можно Тут

makemessages

python manage.py makemessages

Командна для работы с переводами (локализацией) сайтов.

Команда проходит через весь код и ищет места, которые заготовлены для перевода (для Python кода - это везде, где вы используете метод gettext, для шаблонов - везде, где используется темплейт тег translate, подробнее Тут).

Создаёт\обновляет файлы, в которых хранятся\будут храниться переводы текста на друге языки. Принимает параметры --all , --extension, --locale, --exclude, --domain, --ignore и т. д.

Подробности использования параметров тут

Обсудим основные.

--locale LOCALE, -l LOCALE нужно для указания языка, на который планируется перевод (на самом деле повлияет только на то, как будет называться файл с переводами, и как этот перевод будет называться в системе), например, для французского можно назвать файл fr, для итальянского it и т. д.

django-admin makemessages --locale=pt_BR
django-admin makemessages --locale=pt_BR --locale=fr
django-admin makemessages -l pt_BR
django-admin makemessages -l pt_BR -l fr

--ignore PATTERN - игнорировать (не искать) переводы в определённых местах, например, `--ignore *.py' - игнорировать все Python файлы.

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

#. Translators: This message appears on the home page only
# path/to/python/file.py:123
msgid "Welcome to my site."
msgstr ""

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

compilemessages

Компилирует файлы для переводов.

Делает из .po файлов .mo файлы. Django принимает именно .mo в качестве файлов, откуда брать перевод.

Поддерживает указание локали и игнор, подробнее в доке.

createcachedtable

Создаёт таблицу для кеша в базе данных, подробно рассматривали на занятии по сессиям и кешам.

shell

Уже известная вам команда shell открывает интерактивную python консоль с уже импортированными библиотеками вашего проекта, например, Django.

dbshell

По аналогии со знакомой нам командой shell открывает консоль со всеми необходимыми импортированными данными, но для базы данных.

Например, для PostgreSQL, откроется psql и т. д.

diffsettings

Команда, которая покажет, чем отличается ваш файл settings.py от оригинала.

dumpdata

Команда для работы с фикстурами.

Фикстуры - это файлы отображения базы данных в формат JSON.

Команда dumpdata вытащит все данные из базы данных и преобразует всё в формат JSON.

Может принимать имя только нескольких приложений или даже только некоторых моделей, или наоборот - исключить какие-то приложения или модели.

loaddata

Команда, обратная команде dumpdata, для загрузки JSON файла в базу данных.

Подробно будем рассматривать эти командны на практике во время занятия по тестированию Django.

flush

Команда, необходимая для очистки базы данных, но не отмены миграций (сохраняем структуру, теряем все данные).

sqlflush

Отпечатает, какой SQL код будет выполнен при применении команды flush.

inspectdb

Команда, необходимая для проверки соответствия ваших моделей и вашей базы данных. Незаменимо при переносе проекта извне на Django.

makemigrations

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

Может принимать важный параметр --empty, при этом флаге создастся пустая миграция, никак не привязанная к моделям. Выглядеть будет примерно вот так:

# Generated by Django 3.0.7 on 2020-10-29 11:59

from django.db import migrations


class Migration(migrations.Migration):
    dependencies = [
        ('storages', '0003_auto_20201029_1352'),
    ]

    operations = [
    ]

Тут указано приложение, для которого миграция будет применена, и прошлая миграция, с которой текущая миграция будет связана.

Зачем это вообще надо?

Мы можем в операции добавить любые интересующие нас действия, например, выполнения кода на Python.

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

# Generated by Django 3.0.7 on 2020-10-29 11:59

from django.db import migrations


def some_forward_action(apps, schema_editor):
    Team = apps.get_model('storages', 'Team')
    Team.objects.create(name='B2B')
    Team.objects.create(name='CX')
    Team.objects.create(name='SFA')


def some_backward_action(apps, schema_editor):
    pass


class Migration(migrations.Migration):
    dependencies = [
        ('storages', '0003_auto_20201029_1352'),
    ]

    operations = [
        migrations.RunPython(some_forward_action, some_backward_action)
    ]

Такие миграции называются Data Migrations.

Чаще всего для того, чтобы занести какие-либо данные в базу данных на этапе миграции, например, создать заведомо известные объекты, как в моём примере, или для установки вычисляемого значения по умолчанию.

Для обратной миграции чаще всего действия не требуются (хоть и далеко не всегда), поэтому чаще всего обратная миграция записывается в виде лямбды lambda x, y: None

Типовая Data Migration:

# Generated by Django 3.0.7 on 2020-10-29 11:59

from django.db import migrations


def some_forward_action(apps, schema_editor):
    Team = apps.get_model('storages', 'Team') # Приложение и модель
    Team.objects.create(name='B2B')
    Team.objects.create(name='CX')
    Team.objects.create(name='SFA')


class Migration(migrations.Migration):
    dependencies = [
        ('storages', '0003_auto_20201029_1352'),
    ]

    operations = [
        migrations.RunPython(some_forward_action, lambda x, y: None)
    ]

migrate

Уже известная вам команда для применения миграции

django-admin migrate [app_label] [migration_name]

Может быть указано приложение, к которому применяется, и имя миграции (на самом деле достаточно первых четырех цифр). Указывание имени нужно для отката миграций. Допустим, у вас уже применена миграция номер 8, а вы поняли, что проблема была в миграции номер 6, это значит, что можно откатить базу до миграции номер 5. Естественно с потерей данных, и провести новые миграции, для этого нужно сделать:

manage.py migrate my_app 0005

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

Вместо цифр можно указать значение zero, что позволяет откатить все миграции для этого приложения.

sqlmigrate

Отпечатает, какой SQL код будет выполнен при применении команды migrate

showmigrations

Также уже известная вам команда, которая отобразит список миграций и их состояние (применена или нет).

runserver

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

sendtestemail

Отправка тестового имейла (работает, только если отправка писем была настроена) принимает два параметра - от кого и кому.

Например:

python manage.py sendtestemail [email protected] [email protected]

sqlsequencereset

Команда для сброса последовательностей базы данных, может принимать название приложения.

Если вы удалите все объекты из базы и начнёте создавать новые, id будут продолжаться вне зависимости от того, сколько объектов было раньше, потому что id вычисляется из специальных объектов базы, которые называются sequence.

Если их сбросить, то id будет назначаться снова с 1.

Не применять на базах с данными!!

squashmigrations

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

Например, в приложении myapp миграции от 4-ой до 7-ой - это добавления новых полей в одну и ту же модель. Чтобы сжать эти миграции в одну, нужно выполнить:

python manage.py squashmigrations myapp 0004 0007

startapp

Команда для создания нового приложения.

startproject

Команда для создания нового проекта.

test

Команда для запуска тестов. Рассмотрим её на следующих занятиях.

Команды базовых приложений

django.contrib.auth

changepassword

Команда для смены пароля конкретному пользователю.

manage.py changepassword ringo

createsuperuser

Команда для создания пользователя со всеми правами.

django.contrib.sessions

clearsession

Команда для очистки базы данных от информации о сессиях. При базовых настройках вся информация о сессиях автоматически пишется в базу данных.

django.contrib.staticfiles

Команды для статики, вообще работу статики и медиа рассмотрим на следующих занятиях.

Написание своих скриптов

По факту, все вышеописанные команды написаны на Python, а это значит, что мы можем написать свои команды.

Допустим, у нас есть проект пиццерии, в рамках которого есть приложение orders, отвечающее за заказы, и мы хотим, чтобы все заказы, которые не были закрыты вручную, ровно в 18:00 были переведены в статус для ручной проверки, а владелец заведения получил письмо о том, что такие заказы есть.

Самый простой путь - это создать manage-команду. В приложении создадим папку management, а в ней папку commands, названия созданных в этой папке файлов будет соответствовать кастомной manage-команде.

orders/
    __init__.py
    models.py
    management/
        commands/
            close_orders.py
    tests.py
    views.py

В файле нужно создать класс, наследованный от BaseCommand:

from django.core.management.base import BaseCommand
from orders.models import Order
import send_email


class Command(BaseCommand):
    help = "Close orders which weren't closed manually"

    def handle(self, *args, **options):
        orders = Order.objects.filter(status="opened")
        if orders:
            orders.update(status="manual")
            send_email("Not closed orders", f"Hey, you have {orders.count()} orders with status 'opened'")
            self.stdout.write(self.style.SUCCESS('Successfully closed orders'))

Запустить такую команду можно из консоли:

python manage.py close_orders

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

0 18 * * 1-5 /some/path/pizza/manage.py close_orders

Задания

  1. Снять фикстуру с вашей базы, изучить полученный файл.
  2. Для вашего модуля создать дата миграцию, которая будет создавать два новых товара.
  3. Написать manage команду, чтобы отклонить все заявки на возврат.