Модели Django
Нам нужно что-то, что будет хранить все записи нашего блога. Но прежде давай поговорим о вещах, называемых объектами.
Объекты
В программировании существует особая концепция, она называется объектно-ориентированным программированием. Идея заключается в том, что вместо скучной последовательности инструкций мы моделируем вещи и описываем, как они взаимодействуют друг с другом.
Так что же такое объект? Это совокупность поведения и свойств. Звучит странно, но мы приведем пример.
Если мы хотим смоделировать кошку, то создадим объект Cat, который обладает определенными свойствами, например, color (цвет), age (возраст), mood (настроение: плохое, хорошее, сонное ;)), owner (хозяин, например, другой объект — Person — или, если кошка дикая, это свойство будет пустым).
Объект Cat будет иметь набор определённых действий: purr (мурчать), scratch (царапаться) или feed (кормить, где мы дадим кошке немного CatFood — кошачьей еды, которая так же может быть отдельным объектом со своими свойствами, например, taste — вкусом).
Cat
--------
color
age
mood
owner
purr()
scratch()
feed(cat_food)
CatFood
--------
taste
Основная идея, таким образом, заключается в описании объекта в коде, используя его параметры (свойства объекта) и доступные ему действия (методы).
Так как же мы смоделируем запись в блоге? Нам же нужен блог, верно?
Для начала стоит ответить на вопрос: что такое запись в блоге? Какие свойства она имеет?
Ну, запись наверняка содержит какой-то текст и заголовок, верно? Было бы неплохо также знать, кто её написал — так что нам нужен автор. Ну и в заключение, нам нужно знать, когда запись создана и когда опубликована.
Post
--------
title
text
author
created_date
published_date
Какие вещи можно сделать с записью в блоге? Было бы неплохо иметь метод для её публикации, согласна?
Так что нам пригодится метод publish.
Ну и раз уж мы определились с тем, что хотим получить, давай начнем моделирование в Django!
Модель в Django
Зная, что представляет из себя объект, мы можем создать модель Django для записи в блоге.
Модель в Django — это объект определённого свойства: он хранится в базе данных. База данных представляет собой совокупность различных данных. Это то место, где ты будешь хранить информацию о своих пользователях, записях в блоге и т.д. Мы будем использовать базу данных SQLite для хранения информации. Это стандартная база данных в Django — её сейчас вполне хватит для наших нужд.
Ты можешь представить модель в базе данных как электронную таблицу с колонками (полями) и строками (данными).
Создание приложения
Для аккуратности мы создадим отдельное приложение в нашем проекте. Очень удобно иметь хорошо организованное рабочее место с самого начала. Для создания приложения нам понадобится набрать следующую инструкцию в командной строке (из директории djangogirls, где находится файл manage.py):
macOS и Linux:
(myvenv) ~/djangogirls$ python manage.py startapp blog
Windows:
(myvenv) C:\Users\Name\djangogirls> python manage.py startapp blog
Обрати внимание, что в нашем проекте появилась новая папка blog, которая содержит некоторые файлы. Таким образом, структура нашего проекта будет выглядеть так:
djangogirls
├── blog
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── manage.py
└── mysite
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
После того, как приложение создано, нам нужно сообщить Django, что теперь он должен его использовать. Мы сделаем это с помощью файла mysite/settings.py. Нам нужно найти INSTALLED_APPS и добавить к списку 'blog', прямо перед ]. Конечный результат должен выглядеть следующим образом:
mysite/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
Создание модели записи в блоге
В файле blog/models.py мы определяем все Модели — модель записи для блога также пойдёт сюда.
Открой файл blog/models.py, удали весь текст и вставь на его место следующий код:
blog/models.py
from django.conf import settings
from django.db import models
from django.utils import timezone
class Post(models.Model):
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
Убедись, что использовала два символа нижнего подчёркивания (
_) с обеих сторон от методаstr. Это соглашение часто используется при программировании на Python, и иногда его называют "dunder" (сокращение от англ. "double-underscore").
Смотрится страшно, да? Но не волнуйся, мы объясним, что значит каждая строка кода!
Строки, начинающиеся с from или import, открывают доступ к коду из других файлов. Так что вместо того, чтобы копировать и вставлять один и тот же код во все файлы, ты можешь сослаться на него при помощи from ... import ....
class Post(models.Model): — эта строка определяет нашу модель (объект).
class— это специальное ключевое слово для определения объектов.Post— это имя нашей модели, мы можем поменять его при желании (специальные знаки и пробелы использовать нельзя). Всегда начинай имена классов с прописной буквы.models.Modelозначает, что объект Post является моделью Django, так Django поймет, что он должен сохранить его в базу данных.
Дальше мы задаем свойства, о которых уже говорили: title, text, created_date, published_date и author. Чтобы это сделать, нам нужно определиться с типом полей (это текст? число? дата? ссылка на другой объект? например, на пользователя?).
models.CharField— так мы определяем текстовое поле с ограничением на количество символов.models.TextField— так определяется поле для неограниченно длинного текста. Выглядит подходящим для содержимого поста, верно?models.DateTimeField— дата и время.models.ForeignKey— ссылка на другую модель.
Мы не будем объяснять каждую запятую, поскольку на это уйдет слишком много времени. Ознакомься с официальной документаций Django: если хочешь узнать больше о полях моделей и о том, как определять разные объекты, то эта ссылка может помочь: https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types.
Что насчёт def publish(self):? Это как раз метод публикации для записи, о котором мы говорили. def означает, что создаётся функция/метод, а publish — это название этого метода. Можно изменить имя метода, если хочешь. Существует правило для имён функций: нужно использовать строчные буквы, а пробелы заменять на подчёркивания. Например, метод, вычисляющий среднюю цену, может называться calculate_average_price.
Методы часто возвращают что-то. Например, метод __str__. В нашем случае после вызова метода __str__() мы получим текст (строку) с заголовком записи.
Также обрати внимание, что оба метода def publish(self): и def __str__(self): внутри класса имеют дополнительный отступ. Поскольку в Python важны отступы, нам необходимо использовать их для методов внутри класса — иначе методы не будут принадлежать к классу, и при запуске программы может получиться что-то неожиданное.
Если тема моделей тебе до сих пор непонятна — не стесняйся обратиться к тренеру! Мы знаем, что она действительно сложна, особенно когда ты изучаешь параллельно объекты и функции. Но мы надеемся, что всё это больше не кажется тебе магией!
Создаём таблицы моделей в базе данных
Последним шагом будет добавление нашей модели в базу данных. Сначала мы должны дать Django знать, что сделали изменения в нашей модели (мы её только что создали!). Набери python manage.py makemigrations blog. Должно получиться примерно так:
command-line
(myvenv) ~/djangogirls$ python manage.py makemigrations blog
Migrations for 'blog':
blog/migrations/0001_initial.py:
- Create model Post
Примечание: не забудь сохранить отредактированные файлы. Иначе твой компьютер выполнит команду с их предыдущей версией, и могут появиться неожиданные ошибки.
Django создал для нас файл с миграцией для базы данных. Набери python manage.py migrate blog, результат должен быть следующим:
command-line
(myvenv) ~/djangogirls$ python manage.py migrate blog
Operations to perform:
Apply all migrations: blog
Running migrations:
Rendering model states... DONE
Applying blog.0001_initial... OK
Ура! Модель записи для блога теперь в базе данных, и было бы неплохо посмотреть на неё, верно? Тогда переходи к следующей главе!