Написание вашего первого приложения Django, часть 2

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

Где получить помощь:

Если у вас возникли проблемы с этим руководством, перейдите в раздел « Получение справки» в FAQ.

Конфигурация базы данных

А теперь откройся mysite/settings.py . Это совершенно нормальный модуль Python с переменными модуля, которые представляют настройки Django.

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

Если вы хотите использовать другую базу данных, установите разъем базы данных , подходящий и изменить ключ в следующий элемент 'default' из DATABASES индикации настройки подключения к базе данных:

  • ENGINE - Выберите из 'django.db.backends.sqlite3' , 'django.db.backends.postgresql' , 'django.db.backends.mysql' или 'django.db.backends.oracle' . Также доступны другие двигатели .
  • NAME - Название вашей базы данных. Если вы используете SQLite, база данных будет файлом на вашем компьютере; в этом случае NAME должен быть полный абсолютный путь, включая имя файла, этого файла. Значение по умолчанию ,, сохранит файл в каталоге вашего проекта.BASE_DIR / 'db.sqlite3'

Если вы используете базу данных, отличную от SQLite, необходимо указать дополнительные параметры, например USER , PASSWORD или HOST . Подробнее см. Справочную документацию по DATABASES .

Для баз данных, отличных от SQLite

Если вы используете базу данных, отличную от SQLite, убедитесь, что вы создали базу данных. Сделайте это в интерактивной оболочке вашей базы данных.CREATE DATABASE nom_de_la_base;

Также убедитесь, что пользователь базы данных, указанный в файле, mysite/settings.py имеет разрешение на создание баз данных. Это автоматически создаст тестовую базу данных , которая понадобится позже в руководстве.

Если вы используете SQLite, вам не нужно ничего создавать заранее - файл базы данных будет автоматически создан при необходимости.

Поскольку вы редактируете mysite/settings.py , установите в TIME_ZONE соответствии с вашим часовым поясом.

Также обратите внимание на настройку INSTALLED_APPS в начале файла. Эта переменная содержит имя приложений Django, активных в этом экземпляре Django. Приложения можно использовать в разных проектах, а вы можете упаковывать и распространять свои собственные, чтобы другие использовали их в своих проектах.

По умолчанию INSTALLED_APPS содержит следующие приложения, все из которых содержатся в Django:

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

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

$ python manage.py migrate
... \> py manage.py migrate

Команда migrate проверяет настройку INSTALLED_APPS и создает необходимые таблицы базы данных на основе настроек базы данных в вашем файле mysite/settings.py и миграций базы данных, содержащихся в приложении (мы рассмотрим их позже). Вы увидите сообщение для каждой примененной миграции. Если вам интересно, запустите клиент командной строки базы данных и введите \dt (PostgreSQL), (MariaDB, MySQL), (SQLite) или (Oracle), чтобы отобразить таблицы, созданные Django.SHOW TABLES; .schema SELECT TABLE_NAME FROM USER_TABLES;

Для минималистов

Как отмечалось выше, приложения, включенные по умолчанию, являются наиболее распространенными, но они нужны не всем. Если вам не нужен один из них (или все они), вы можете прокомментировать или удалить соответствующие строки из настройки INSTALLED_APPS перед началом migrate . Команда migrate выполнит миграцию только для приложений, перечисленных в INSTALLED_APPS .

Создание моделей

Теперь мы определим модели - в основном схему базы данных с некоторыми дополнительными метаданными.

философия

Модель - это единственный и окончательный источник информации для ваших данных. Он содержит основные поля и ожидаемое поведение данных, которые вы будете хранить. Django уважает философию DRY (Don't Repeat Yourself, «не повторяйся»). Цель состоит в том, чтобы определить модель данных в одном месте, а затем автоматически извлечь из нее все, что необходимо.

Это включает миграции. В отличие от Ruby On Rails, например, миграции полностью производятся из файла моделей и в основном представляют собой просто историю, которую Django может просмотреть, чтобы обновить схему базы данных в соответствии с моделями. ток.

В нашем приложении для опроса мы создадим две модели: Question и Choice (выбор). У одного Question есть вопрос и дата публикации. У выбора есть два поля: текст, представляющий выбор, и подсчет голосов. Каждый выбор связан с одним Question .

Эти концепции представлены классами Python. Отредактируйте файл polls/models.py так, чтобы он выглядел так:

polls / models.py
from django.db import models


class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')


class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

Здесь каждая модель представлена ​​классом, наследуемым от django.db.models.Model . Каждая модель имеет переменные класса, каждая из которых представляет поле в базе данных для этой модели.

Каждое поле представлено экземпляром класса Field - например, CharField для символьных полей, а также DateTimeField для полей даты и времени. Это сообщает Django, какой тип данных содержит каждое поле.

Имя каждого экземпляра Field (например, question_text или pub_date ) - это внутреннее имя поля. Вы будете использовать его в своем коде Python, а ваша база данных будет использовать его в качестве имени столбца.

Вы можете использовать первый (необязательный) параметр позиции, Field чтобы дать полю более читаемое имя. Это используется системой самоанализа Django, а также для документации. Если этот параметр отсутствует, Django будет использовать имя внутреннего поля. В этом примере мы определили только еще одно читаемое имя для Question.pub_date . Для всех остальных полей мы посчитали, что внутреннее имя достаточно читабельно.

У некоторых классов Field есть обязательные параметры. Классу CharField , например, нужен атрибут max_length . Это используется не только в базовой схеме базы данных, но и для проверки полей, как мы вскоре увидим.

Поле Field также может допускать необязательные параметры; В нашем случае, мы установили значение default от 0 , votes .

Наконец, обратите внимание, что мы определяем отношение, используя ForeignKey . Это сообщает Django, что каждое голосование ( Choice ) связано только с одним Question . Django предлагает все классические модели отношений: многие к одному, многие ко многим, один к одному.

Активация моделей

Этот небольшой фрагмент кода, описывающий модели, предоставляет много информации для Django. Это позволяет ему:

  • Создайте схему базы данных (инструкции ) для этого приложения.CREATE TABLE
  • Создайте API доступа к базе данных Python для доступа к объектам Question и Choice .

Но сначала мы должны сообщить нашему проекту, что приложение для опросов polls установлено.

философия

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

Чтобы включить приложение в наш проект, нам нужно добавить ссылку на его класс конфигурации в параметр INSTALLED_APPS . Класс PollsConfig находится в файле polls/apps.py , что означает его указанный путь 'polls.apps.PollsConfig' . Отредактируйте файл mysite/settings.py и добавьте этот пунктирный путь к настройке INSTALLED_APPS . Должно получиться так:

mysite / settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Теперь Django знает, что ему нужно включить приложение polls . Запустим еще одну команду:

$ python manage.py makemigrations polls
... \> py manage.py опросы makemigrations

Вы должны увидеть что-то похожее на это:

Migrations for 'polls':
  polls/migrations/0001_initial.py
    - Create model Question
    - Create model Choice

Запустив makemigrations , вы сообщаете Django, что вы внесли изменения в свои модели (в данном случае вы создали некоторые из них) и хотите, чтобы эти изменения сохранялись как миграция .

Миграции - это способ Django сохранять изменения в ваших моделях (и, следовательно, в вашей схеме базы данных), это файлы на диске. Вы можете проверить миграцию для ваших новых моделей, если хотите; это файл polls/migrations/0001_initial.py . Будьте уверены, вы не должны читать их каждый раз, когда Django создает их, но они предназначены для чтения человеком, если вам нужно вручную адаптировать процессы редактирования Django.

Это команда, которая запускает миграции и автоматически управляет схемой вашей базы данных migrate . Мы скоро к этому вернемся, но сначала давайте посмотрим на операторы SQL, которые создает миграция. Команда sqlmigrate принимает имена миграций и отображает соответствующий код SQL:

$ python manage.py sqlmigrate polls 0001
... \> py manage.py sqlmigrate опросы 0001

Вы должны увидеть нечто подобное (переформатировано для удобства чтения):

BEGIN;
--
-- Create model Question
--
CREATE TABLE "polls_question" (
    "id" serial NOT NULL PRIMARY KEY,
    "question_text" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL,
    "question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");

COMMIT;

Обратите внимание на следующее:

  • То, что вы увидите, будет зависеть от используемой вами базы данных. Приведенный выше пример создан для PostgreSQL.
  • Имена таблиц генерируются автоматически путем объединения имени приложения ( polls ) и имени модели в нижнем регистре - question и choice (это поведение можно изменить).
  • Первичные ключи (ID) добавляются автоматически (вы тоже можете это изменить).
  • По соглашению Django добавляет "_id" имя поля внешнего ключа. И да, вы тоже можете это изменить.
  • Связь внешнего ключа явно выражается ограничением . Не обращайте внимания на детали ; они говорят PostgreSQL не проверять внешний ключ до завершения транзакции.FOREIGN KEY DEFERRABLE
  • То, что вы видите, относится к используемой вами базе данных. Таким образом, специфические для этого поля, такие как auto_increment (MySQL), serial (PostgreSQL) или (SQLite), управляются автоматически. Что касается кавычек вокруг названий полей (одинарных или двойных).integer primary key autoincrement
  • На sqlmigrate самом деле команда не выполняет миграцию в вашей базе данных - она ​​просто отображает ее на экране, чтобы вы могли видеть любой код SQL, который, по мнению Django, вам нужен. Это полезно, чтобы узнать, что собирается делать Django, или если у вас есть администраторы баз данных, которым требуются сценарии SQL для внесения изменений.

Если вам интересно, вы также можете запустить ; эта команда проверяет соответствие вашего проекта без применения миграции и без обращения к базе данных.python manage.py check

Теперь снова запустите команду, migrate чтобы создать таблицы моделей в базе данных:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK
...\> py manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK

Команда migrate выбирает все миграции, которые не были применены (Django отслеживает примененные миграции, используя специальную таблицу в базе данных :), django_migrations а затем выполняет их в базе данных, которая в основном синхронизирует изменения модели со схемой базы данных.

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

  • Отредактируйте шаблоны (в models.py ).
  • Выполните, чтобы создать миграции, соответствующие этим изменениям.python manage.py makemigrations
  • Выполните, чтобы применить эти изменения к базе данных.python manage.py migrate

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

Прочтите документацию django-admin для получения всей информации о том, что manage.py можно делать.

Игра с программным интерфейсом (API)

Теперь давайте воспользуемся интерактивной оболочкой Python, чтобы поиграть с API, который Django предоставляет вам бесплатно. Чтобы запустить оболочку Python, используйте эту команду:

$ python manage.py shell
...\> py manage.py shell

Мы используем это вместо того, чтобы просто набирать "python", потому что manage.py устанавливаетDJANGO_SETTINGS_MODULE переменная среды, которая дает Django путь импорта Python к вашему mysite/settings.py файлу.

Оказавшись в оболочке, изучите API базы данных :

>>> from polls.models import Choice, Question  # Import the model classes we just wrote.

# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>

# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# Save the object into the database. You have to call save() explicitly.
>>> q.save()

# Now it has an ID.
>>> q.id
1

# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

Второй. не очень полезное представление этого объекта. Мы исправим это, отредактировав модель (в файле ) и добавив метод в и в :<Question: Question object (1)> Question polls/models.py __str__() Question Choice

polls / models.py
from django.db import models

class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text

Важно добавлять методы __str__() в ваши модели не только потому, что это более удобно при использовании интерактивной оболочки, но и потому, что представление объектов широко используется в автоматическом интерфейсе администратора Django.

Давайте также добавим в этот шаблон собственный метод:

polls / models.py
import datetime

from django.db import models
from django.utils import timezone


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

Обратите внимание на добавление и для ссылки на стандартный модуль Python и утилиты Django, связанные с часовыми поясами . Если вы не знакомы с обработкой часовых поясов с помощью Python, вы можете узнать больше, просмотрев документацию по часовым поясам .import datetime from django.utils import timezone datetime django.utils.timezone

Сохраните эти изменения и вернемся к интерактивной оболочке Python, запустив снова :python manage.py shell

>>> from polls.models import Choice, Question

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

Для получения дополнительной информации о взаимосвязях между моделями см. Доступ к связанным объектам . Чтобы узнать больше о том, как использовать двойное подчеркивание для перехода к полям через API, см. Поиск в полях . Полную информацию об API базы данных см. В справочнике по API базы данных .

Знакомство с сайтом администрирования Django

философия

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

Django был написан в редакционной среде с очень четким разделением между «редакторами контента» и «общедоступным» сайтом. Менеджеры сайтов используют систему для добавления новостей, историй, событий, спортивных результатов и т. Д., И этот контент размещается на общедоступном сайте. Django устраняет проблему создания единого интерфейса для администраторов сайта, редактирующих контент.

Интерфейс администрирования не предназначен для использования посетителями сайта; он предназначен для менеджеров сайтов.

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

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

$ python manage.py createsuperuser
...\> py manage.py createsuperuser

Введите желаемое имя пользователя и нажмите клавишу возврата.

Username: admin

Затем вас попросят ввести желаемый адрес электронной почты:

Email address: [email protected]

Последний шаг - ввести пароль. Вас просят ввести его дважды, второй раз является подтверждением первого.

Password: **********
Password (again): *********
Superuser created successfully.

Запуск сервера разработки

Сайт администратора Django включен по умолчанию. Запустим сервер разработки и исследуем его.

Если сервер еще не запущен, запустите его так:

$ python manage.py runserver
...\> py manage.py runserver

Теперь откройте веб-браузер и перейдите по URL-адресу «/ admin /» вашего локального домена - например, http://127.0.0.1:8000/admin/ . Вы должны увидеть экран входа в интерфейс администратора.

Поскольку перевод активен по умолчанию, если вы установите его LANGUAGE_CODE , экран входа в систему будет отображаться на этом языке (если соответствующие переводы существуют в Django).

Вход на сайт администрирования

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

Вы должны увидеть несколько типов редактируемого контента: группы и пользователей. Они предоставляются системой django.contrib.auth аутентификации, поставляемой с Django.

Сделайте приложение опроса доступным для редактирования через интерфейс администратора

Но где же наше приложение для опросов? Он не отображается на главной странице интерфейса администрирования.

Можно сделать несколько вещей: вы должны сообщить администратору, что у объектов Question есть административный интерфейс. Для этого откройте файл polls/admin.py и отредактируйте его следующим образом:

polls/admin.py
from django.contrib import admin

from .models import Question

admin.site.register(Question)

Изучение возможностей интерфейса администрирования

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

Щелкните «Вопросы». Теперь вы находитесь на странице вопросов со списком изменений. На этой странице отображаются все вопросы из базы данных, и вы можете выбрать один из них, чтобы изменить его. Возникает вопрос "Что нового?" »Что мы создали ранее.

Щелкните вопрос "Что нового?" чтобы изменить это.

Обратите внимание:

  • Форма автоматически создается из шаблона Question .
  • Различные типы полей шаблона ( DateTimeField , CharField ) соответствуют соответствующему входному графическому компоненту HTML. Каждый тип поля знает, как отображаться в интерфейсе администратора Django.
  • Каждый DateTimeField автоматически получает ярлыки JavaScript. Даты получают ярлык «Сегодня» и всплывающий календарь, а «Таймс» - ярлык «Сейчас» и удобное всплывающее окно со списком часто вводимого времени.

В нижней части страницы предлагается ряд операций:

  • Сохранить - сохранить изменения и вернуться на страницу со списком для модификации этого типа объекта.
  • Сохранить и продолжить изменения - сохраняет изменения и перезагружает страницу администрирования для этого объекта.
  • Сохранить и добавить новый - сохраняет изменения и загружает новую пустую форму для этого типа объекта.
  • Удалить - отображает страницу подтверждения удаления.

Если значение «Дата публикации» не соответствует времени, когда вы создали этот вопрос в Уроке 1 , вы, вероятно, забыли установить правильное значение для параметра TIME_ZONE . Отредактируйте его, перезагрузите страницу и убедитесь, что отображается правильное значение.

Измените «Дата публикации», щелкнув ярлыки «Сегодня» и «Сейчас». Затем нажмите «Сохранить и продолжить изменения». Затем нажмите «История» в правом верхнем углу страницы. Вы увидите страницу со списком всех изменений, внесенных в этот объект через интерфейс администратора Django, вместе с датой и временем, а также с именем пользователя, который внес это изменение.

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

Copyright ©2020 All rights reserved