Изучаем Python Эрик Метиз. Crash course2 n d e d i t i o na h a n d s o n, p r o j e c t b a s e d i n t r o d u c t i o n t o p r o g r a m m i n g
Скачать 6.19 Mb.
|
python manage.py migrate ❶ Operations to perform: Apply all migrations: admin, auth, contenttypes, sessions Running migrations: Applying contenttypes.0001_initial... OK Applying auth.0001_initial... OK Applying sessions.0001_initial... OK ❷ (ll_env)learning_log$ ls db.sqlite3 learning_log ll_env manage.py Каждое изменение базы данных называется миграцией. Первое выполнение коман- ды migrate приказывает Django проверить, что база данных соответствует текуще- му состоянию проекта. Когда мы впервые выполняем эту команду в новом проекте с использованием SQLite (вскоре мы расскажем о SQLite более подробно), Django создает новую базу данных за нас. В точке Django сообщает о создании и под- готовке базы данных к хранению информации, необходимой для выполнения административных операций и аутентификации. Выполнение команды ls показывает, что Django создает другой файл с именем db .sqlite3 . SQLite — база данных, работающая с одним файлом; она идеально Подготовка к созданию проекта 397 подходит для написания простых приложений, потому что вам не нужно особенно следить за управлением базой данных. ПРИМЕЧАНИЕ В активной виртуальной среде для выполнения команд manage .py ис- пользуется команда python, даже если для запуска других программ вы используете другую команду (например, python3) . В виртуальной среде команда python относится к версии Python, создавшей виртуальную среду . Просмотр проекта Убедимся в том, что проект был создан правильно. Введите команду runserver для просмотра текущего состояния проекта: (ll_env)learning_log$ python manage.py runserver Watchman unavailable: pywatchman not installed. Watching for file changes with StatReloader Performing system checks... ❶ System check identified no issues (0 silenced). February 18, 2019 - 16:26:07 ❷ Django version 2.2.0, using settings 'learning_log.settings' ❸ Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. Django запускает сервер, называемый сервером разработки, чтобы вы могли про- смотреть проект в своей системе и проверить, как он работает. Когда вы запраши- ваете страницу, вводя URL в браузере, сервер Django отвечает на запрос; для этого он строит соответствующую страницу и отправляет страницу браузеру. В точке Django проверяет правильность созданного проекта; в точке выво- дится версия Django и имя используемого файла настроек; в точке возвращается URL-адрес, по которому доступен проект. URL http://127 .0 .0 .1:8000/ означает, что проект ведет прослушивание запросов на порте 8000 локального хоста (localhost), то есть вашего компьютера. Термином «локальный хост» обозначается сервер, который обрабатывает только запросы вашей системы; он не позволяет никому другому просмотреть разрабатываемые страницы. Теперь откройте браузер и введите URL http://localhost:8000/ — или http://127 .0 .0 .1:8000/ , если первый адрес не работает. Вы увидите нечто похожее на рис. 18.1 — страницу, которую создает Django, чтобы сообщить вам, что все пока работает правильно. Пока не завершайте работу сервера (но когда вы захотите пре- рвать ее, это можно сделать нажатием клавиш Ctrl+C в терминале, в котором была введена команда runserver ). ПРИМЕЧАНИЕ Если вы получаете сообщение об ошибке «Порт уже использует- ся», прикажите Django использовать другой порт; для этого введите команду python manage.py runserver 8001 и продолжайте перебирать номера портов по возрастанию, пока не найдете открытый порт . 398 Глава 18 • Знакомство с Django Рис. 18.1. Пока все работает правильно УПРАЖНЕНИЯ 18.1. Новые проекты: чтобы лучше понять, что делает Django, постройте пару пустых про- ектов и посмотрите, что произойдет. Создайте новый каталог с простым именем типа snap_ gram или insta_chat (за пределами каталога learning_log ), перейдите в этот каталог в тер- минальном окне и создайте виртуальную среду. Установите Django и выполните коман ду django-admin.py startproject snap_gram (обратите внимание на точку в конце команды). Просмотрите файлы и каталоги, созданные командой, и сравните их с файлами и катало- гами Learning Log. Проделайте это несколько раз, пока не начнете хорошо понимать, что именно делает Django при создании нового проекта, а затем удалите каталоги проектов. Начало работы над приложением Проект Django представляет собой группу отдельных приложений, совместная работа которых обеспечивает работу проекта в целом. Пока мы создадим одно приложение, которое будет выполнять большую часть работы в нашем проекте. Другое приложение для управления учетными записями пользователей будет до- бавлено в главе 19. Оставьте сервер разработки выполняться в терминальном окне, открытом ранее. Откройте новое терминальное окно (или вкладку) и перейдите в каталог, со- держащий manage .py . Активизируйте виртуальную среду и выполните команду startapp : learning_log$ source ll_env/bin/activate (ll_env)learning_log$ python manage.py startapp learning_logs ❶ (ll_env)learning_log$ ls Начало работы над приложением 399 db.sqlite3 learning_log learning_logs ll_env manage.py ❷ (ll_env)learning_log$ ls learning_logs/ admin.py __init__.py migrations models.py tests.py views.py Команда startapp имя_приложения приказывает Django создать инфраструктуру, необходимую для построения приложения. Заглянув сейчас в каталог проекта, вы найдете в нем новый подкаталог с именем learning_logs . Откройте этот каталог, чтобы увидеть, какие файлы были созданы Django . Самые важные файлы в этом каталоге — models .py , admin .py и views .py . Файл models .py будет использоваться для определения данных, которыми нужно управлять в нашем приложении. К файлам admin .py и views .py мы вернемся позднее. Определение моделей Подумаем, какие данные нам понадобятся. Каждый пользователь создает набор тем в своем журнале. Каждая запись, которую он сделает, будет привязана к опре- деленной теме, а записи будут выводиться в текстовом виде. Также необходимо хранить временную метку каждой записи, чтобы пользователь знал, когда эта за- пись была создана. Откройте файл models .py и просмотрите его текущее содержимое: models.py from django.db import models # Создайте здесь свои модели. Модуль с именем models импортируется автоматически, и нам предлагается создать свои модели. Модель сообщает Django, как работать с данными, которые будут хра- ниться в приложении. С точки зрения кода модель представляет собой обычный класс; она содержит атрибуты и методы, как и все остальные классы, рассматри- вавшиеся нами ранее. Вот как выглядит модель тем обсуждения, которые будут сохраняться пользователями: from django.db import models class Topic(models.Model): """Тема, которую изучает пользователь""" ❶ text = models.CharField(max_length=200) ❷ date_added = models.DateTimeField(auto_now_add=True) ❸ def __str__(self): """Возвращает строковое представление модели.""" return self.text Мы создали класс с именем Topic , наследующий от Model — родительского клас- са, включенного в Django и определяющего базовую функциональность модели. В класс Topic добавляются два атрибута: text и date_added 400 Глава 18 • Знакомство с Django Атрибут text содержит данные CharField — блок данных, состоящий из символов, то есть текст . Атрибуты CharField могут использоваться для хранения неболь- ших объемов текста: имен, заголовков, названий городов и т. д. При определении атрибута CharField необходимо сообщить Django, сколько места нужно зарезер- вировать для него в базе данных. В данном случае задается максимальная длина max_length , равная 200 символам; этого должно быть достаточно для хранения большинства имен тем. Атрибут date_added содержит данные DateTimeField — блок данных для хранения даты и времени . Аргумент auto_add_now=True приказывает Django автоматически присвоить этому атрибуту текущую дату и время каждый раз, когда пользователь создает новую тему. ПРИМЕЧАНИЕ Полный список всех полей, которые могут использоваться в моде- ли, приведены в документе Django Model Field Reference на https://docs .djangoproject .com/ en/2 .2/ref/models/fields/ . Возможно, вся эта информация вам сейчас не понадобится, но она будет в высшей степени полезной, когда вы начнете разрабатывать собственные приложения . Необходимо сообщить Django, какой атрибут должен использоваться по умолча- нию при вводе информации о теме. Django вызывает метод __str__() для вывода простого представления модели. Мы написали реализацию __str__() , которая возвращает строку, хранящуюся в атрибуте text . Активизация моделей Чтобы использовать модели, необходимо приказать Django включить приложение в общий проект. Откройте файл settings .py (из каталога learning_log/learning_log ) и найдите в нем раздел, который сообщает Django, какие приложения установлены в проекте: settings.py INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ) Добавьте наше приложение в этот кортеж; измените содержимое INSTALLED_APPS , чтобы оно выглядело так: INSTALLED_APPS = ( # Мои приложения Начало работы над приложением 401 'learning_logs', # Приложения django по умолчанию. 'django.contrib.admin', ] Группировка приложений в проекте упрощает управление ими по мере того, как проект растет, а количество приложений увеличивается. Здесь мы создаем раздел, который пока содержит только приложение learning_logs . Очень важно разме- стить свои приложения перед приложениями по умолчанию на случай, если вам понадобится переопределить поведение таких приложений. Затем необходимо приказать Django изменить базу данных для хранения инфор- мации, относящейся к модели Topic . В терминальном окне введите следующую команду: (ll_env)learning_log$ python manage.py makemigrations learning_logs Migrations for 'learning_logs': learning_logs/migrations/0001_initial.py - Create model Topic (ll_env)learning_log$ По команде makemigrations Django определяет, как изменить базу данных для хранения информации, связанной с новыми моделями. Из результатов видно, что Django создает файл миграции с именем 0001_initial .py . Эта миграция создает в базе данных таблицу для модели Topic Теперь применим миграцию для автоматического изменения базы данных: (ll_env)learning_log$ python manage.py migrate Operations to perform: Apply all migrations: admin, auth, contenttypes, learning_logs, sessions Running migrations: ❶ Applying learning_logs.0001_initial... OK Большая часть вывода этой команды совпадает с выводом, полученным при первом выполнении команды migrate . Обратить внимание следует на строку ; здесь Django подтверждает, что применение миграции для learning_logs прошло успешно. Каждый раз, когда вы захотите изменить данные, которыми управляет Learning Log, выполните эти три действия: внесите изменения в models .py , вызовите makemigrations для learning_logs и прикажите Django выполнить миграцию проекта ( migrate ). Административный сайт Django Django позволяет легко работать с моделями, определенными для приложения, через административный сайт. Этот сайт используется администраторами сайта, 402 Глава 18 • Знакомство с Django а не рядовыми пользователями. В этом разделе мы создадим административный сайт и используем его для добавления некоторых тем через модель Topic Создание суперпользователя Django позволяет создать пользователя, обладающего полным набором привилегий на сайте; такой пользователь называется суперпользователем. Привилегии управля- ют действиями, которые разрешено выполнять пользователю. На самом жестком уровне привилегий пользователь может только читать общедоступную информа- цию на сайте. Зарегистрированным пользователям обычно предоставляется при- вилегия чтения своих приватных данных, а также избранной информации, доступ- ной только для участников сообщества. Для эффективного администрирования веб-приложения владельцу сайта обычно должна быть доступна вся информация, хранящаяся на сайте. Хороший администратор внимательно относится к конфи- денциальной информации пользователя, потому что пользователи доверяют тем приложениям, с которыми они работают. Чтобы создать суперпользователя в Django, введите следующую команду и ответьте на запросы: (ll_env)learning_log$ python manage.py createsuperuser ❶ Username (leave blank to use 'eric'): ll_admin ❷ Email address: ❸ Password: Password (again): Superuser created successfully. (ll_env)learning_log$ При получении команды createsuperuser Django предлагает ввести имя пользо- вателя, который является суперпользователем . Здесь мы вводим имя ll_admin , но вы можете ввести любое имя на свое усмотрение. Также можно ввести адрес электронной почты или оставить это поле пустым . После этого следует дважды ввести пароль . ПРИМЕЧАНИЕ Часть конфиденциальной информации может быть скрыта от адми- нистраторов сайта . Например, Django на самом деле не сохраняет введенный пароль; вместо этого сохраняется хеш — специальная строка, построенная на основе пароля . И когда в будущем вы вводите пароль, Django снова хеширует введенные данные и срав- нивает результат с хранимым хешем . Если два хеша совпадают, то проверка пройдена . Если же хакер в результате атаки получит доступ к базе данных сайта, то он сможет прочитать только хранящийся в базе хеш, но не пароли . При правильной настройке сайта восстановить исходные пароли из хешей почти невозможно . Регистрация модели на административном сайте Django добавляет некоторые модели (например, User и Group ) на административ- ный сайт автоматически, но модели, которые мы создали, придется регистрировать вручную. Начало работы над приложением 403 При запуске приложения learning_logs Django создает файл admin .py в одном каталоге с models .py . Откройте файл admin .py : admin.py from django.contrib import admin # Зарегистрируйте здесь ваши модели. Чтобы зарегистрировать Topic на административном сайте, введите следующую команду: from django.contrib import admin ❶ from .models import Topic ❷ admin.site.register(Topic) Этот код импортирует регистрируемую модель Topic . Точка перед models со- общает Django, что файл models .py следует искать в одном каталоге с admin .py Вызов admin.site.register() сообщает Django, что управление моделью должно осуществляться через административный сайт . Теперь используйте учетную запись суперпользователя для входа на администра- тивный сайт. Введите адрес http://localhost:8000/admin/ , затем имя пользователя и па- роль для только что созданного суперпользователя, и вы увидите экран наподобие изображенного на рис. 18.2. На этой странице можно добавлять новых пользовате- лей и группы, а также вносить изменения в уже существующие настройки. Также можно работать с данными, связанными с только что определенной моделью Topic Рис. 18.2. Административный сайт с включением модели Topic 404 Глава 18 • Знакомство с Django ПРИМЕЧАНИЕ Если в браузере появляется сообщение о недоступности веб-страницы, убедитесь в том, что сервер Django работает в терминальном окне . Если сервер не ра- ботает, активизируйте виртуальную среду и снова введите команду python manage. py runserver . Если у вас возникнут проблемы с просмотром проекта в любой момент в процессе разработки, закройте все открытые терминалы и снова введите команду runserver; это станет хорошим первым шагом в процессе диагностики . Добавление тем Когда модель Topic была зарегистрирована на административном сайте, добавим первую тему. Щелкните на ссылке Topics , чтобы перейти к странице Topics ; страница практически пуста, потому что еще нет ни одной темы для выполнения операций. Щелкните на ссылке Add Topic ; открывается форма для добавления новой темы. Вве- дите в первом поле текст Chess и щелкните на ссылке Save . Вы возвращаетесь к ад- министративной странице Topics , на которой появляется только что созданная тема. Создадим вторую тему, чтобы у вас было больше данных для работы. Снова щелк- ните на ссылке Add Topic и создайте вторую тему Rock Climbing . Ссылка Save снова возвращает вас к основной странице Topics , где отображаются обе темы, Chess и Rock Climbing Определение модели Entry Чтобы сохранить информацию о том, что вы узнали по этим двум темам, необходи- мо определить модель для записей, которые пользователь делает в своих журналах. Каждая запись должна ассоциироваться с конкретной темой. Такое отношение называется отношением «многие к одному», поскольку многие записи могут быть связаны с одной темой. Код модели Entry (из файла models .py ) выглядит так: models.py from django.db import models class Topic(models.Model): ❶ class Entry(models.Model): """Информация, изученная пользователем по теме""" ❷ topic = models.ForeignKey(Topic, on_delete=models.CASCADE) ❸ text = models.TextField() date_added = models.DateTimeField(auto_now_add=True) ❹ class Meta: verbose_name_plural = 'entries' def __str__(self): """Возвращает строковое представление модели.""" ❺ return f"{self.text[:50]}..." Начало работы над приложением 405 Класс Entry наследует от базового класса Model , как и рассмотренный ранее класс Topic . Первый атрибут, topic , является экземпляром ForeignKey . Термин внешний ключ (foreign key) происходит из теории баз данных; внешний ключ со- держит ссылку на другую запись в базе данных. Таким образом каждая запись связывается с конкретной темой. Каждой теме при создании присваивается ключ, или идентификатор. Если потребуется установить связь между двумя записями данных, Django использует ключ, связанный с каждым блоком информации. Вскоре мы используем такие связи для получения всех записей, связанных с заданной те- мой. Аргумент on_delete=models.CASCADE сообщает Django, что при удалении темы все записи, связанные с этой темой, также должны быть удалены (это называется каскадным удалением). Затем идет атрибут с именем text , который является экземпляром TextField . Полю такого типа ограничение размера не требуется, потому что размер отдельных записей не ограничивается. Атрибут date_added позволяет отображать записи в по- рядке их создания и снабжать каждую запись временной меткой. В точке класс Meta вкладывается в класс Entry . Класс Meta хранит дополнитель- ную информацию по управлению моделью; в данном случае он позволяет задать специальный атрибут, который приказывает Django использовать форму мно- жественного числа Entries при обращении более чем к одной записи. (Без этого Django будет использовать неправильную форму Entrys .) Метод __str__() сообщает Django, какая информация должна отображаться при обращении к отдельным записям. Так как запись может быть достаточно длинным блоком текста, мы приказываем Django выводить только первые 50 символов . Также добавляется многоточие — признак вывода неполного текста. Миграция модели Entry Так как мы добавили новую модель, миграцию базы данных необходимо провести снова. Вскоре вы привыкнете к этому процессу: вы изменяете models .py , выполняете команду python manage.py makemigrations имя_приложения, а затем команду python manage.py migrate Проведите миграцию базы данных и проверьте вывод: (ll_env)learning_log$ |