Django моделі
Наразі ми б хотіли створити щось, що зберігатиме усі дописи в нашому блозі. Але щоб бути спроможними це зробити, нам необхідно трохи поговорити про таке поняття, як об'єкти objects
.
Об'єкти
Існує така концепція в програмуванні, яка називається Об'єктно-орієнтовне програмування
. Ідея полягає в тому, що замість написання нудної послідовності програмних інструкцій ми можемо моделювати речі і визначати як вони будуть взаємодіяти одна з одною.
Отже, що ж таке об'єкт? Це набір властивостей та дій. Звучить дивно, але представимо приклад.
Якщо ми хочемо змоделювати кота, то створимо об'єкт Cat
, що має деякі властивості, наприклад, колір, вік, настрій, власник - color
, age
, mood
(хороший, поганий, сонний ;)), owner
(це буде об'єкт Person
або, можливо, у випадку бездомного кота, ця властивість буде пустою).
Далі припустимо, що наш кіт Cat
має певний набір дій, наприклад, муркотіти, шкрябатися, їсти - purr
, scratch
, feed
(де ми будемо давати коту певний котячий корм CatFood
, котрий міг би бути окремим об'єктом зі своїми властивостями, наприклад, смак - taste
).
Cat
--------
color
age
mood
owner
purr()
scratch()
feed(cat_food)
CatFood
--------
taste
Отже, основна ідея полягає в тому, щоб описати реальні речі в програмному коді з усіма їх властивостями (так званими властивостями об'єкта object properties
) і діями (так званими методами methods
).
Як же ми тоді змоделюємо дописи у блозі? Ми ж хочемо створити блог, правда?
Нам треба відповісти на питання: що таке допис у блозі? Які властивості він повинен мати?
Однозначно наш допис повинен містити певний текст із змістом і заголовком, правда ж? Було б також непогано знати хто його написав, отже нам потрібен автор. Зрештою, ми б хотіли знати коли було створено і опубліковано цей допис.
Post
--------
title
text
author
created_date
published_date
Якого роду дії можна було б вчиняти з дописом у блозі? Було б непогано мати певний метод, що публікує допис, правда ж?
Отже, нам потрібен метод publish
.
Таким чином, знаючи, чого ми хочемо досягти, можемо почати моделювати це в Django!
Django модель
Знаючи яким є наш об'єкт, можемо створити Django модель для допису у нашому блозі.
Модель в Django - це спеціальний вид об'єкту, який зберігається в базі даних. База даних є набором певних даних. Це є місце, де ви будете зберігати інформацію про користувачів, дописи у вашому блозі тощо. Надалі для зберігання наших даних будемо використовувати базу даних SQLite. Це база даних, що встановлена в Django за замовчуванням і, цього буде наразі для нас достатньо.
Ви можете уявляти модель в базі даних як таблицю зі стовпчиками (полями) та рядками (дані).
Створення додатку
Щоб підтримувати все у порядку, створимо окремий додаток всередині нашого проекту. Дуже добре зберігати в усьому організованість з самого початку. Щоб створити додаток треба запустити наступну команду в консолі (з директорії djangogirls
, де знаходиться файл manage.py
):
(myvenv) ~/djangogirls$ python manage.py startapp blog
Ви побачите, що створено нову директорію blog
, яка містить певну кількість файлів. Директорії та файли в нашому проекті мають виглядати наступним чином:
djangogirls
├── mysite
| __init__.py
| settings.py
| urls.py
| wsgi.py
├── manage.py
└── blog
├── migrations
| __init__.py
├── __init__.py
├── admin.py
├── models.py
├── tests.py
└── views.py
Після створення ми також повинні повідомити Django, що він має використовувати цей додаток. Ми робимо це у файлі mysite/settings.py
. Нам треба знайти INSTALLED_APPS
та додати рядок 'blog',
зверху над )
. Таким чином, остаточний результат повинен мати наступний вигляд:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
)
Створення моделі допису у блозі
У файлі blog/models.py
ми визначаємо всі об'єкти, що називаються моделі - Models
. Це і є місце, де ми будемо визначати наш допис.
Відкриємо 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):
- цей рядок визначає нашу модель (це об'єкт object
).
class
- це спеціальне ключове слово, яке показує що ми визначаємо об'єкт.Post
- це ім'я нашої моделі. Ми можемо давати їй різні імена (але ми повинні уникати використання спеціальних символів та пробілів). Завжди починайте ім'я класу із великої літери.models.Model
означає, що Post є Django моделлю, отже Django знає, що вона повинна бути збережена у базі даних.
А зараз визначимо властивості, про які ми говорили перед цим: title
, text
, created_date
, published_date
і author
. Щоб це зробити нам необхідно визначити тип поля (чи це текст? Число? Дата? Зв'язок із іншим об'єктом, наприклад, об'єкт користувач - User?).
models.CharField
- для текстових полів з обмеженням кількісті символів.models.TextField
- великі блоки тексту без обмежень. Ідеально підходить для запису блогу, правильно?models.DateTimeField
- дата та час.models.ForeignKey
- зв'язок із іншою моделлю.
Не будемо пояснювати кожне слово в коді, оскільки це може зайняти надто багато часу. Якщо хочете дізнатися більше про поля моделей, а також як визначати речі відмінні від вище описаних, то дивіться документацію Django (https://docs.djangoproject.com/en/1.11/ref/models/fields/#field-types).
А як щодо def publish(self):
? Це і є наш метод publish
, про який ми говорили раніше. def
означає, що це функція/метод, а publish
- ім'я методу. Ви можете змінити ім'я методу, якщо захочете. Правило іменування: треба використовувати рядкові букви, а пробіли замінювати підкресленнями. Наприклад, метод для розрахунку середньої ціни може бути названий calculate_average_price
.
Методи часто повертають (return
) щось. Приклад цього можна побачити в методі __str__
. У цьому сценарії, коли ми викликаємо __str__()
, то отримуємо текст (string) із заголовком посту.
Якщо вам щось незрозуміло з приводу моделей, не соромтеся запитувати у вашого тренера! Ми знаємо, що це дуже складно, особливо коли ви одночасно вивчаєте об'єкти і функції. Але сподіваємося наразі це виглядає трохи менш таємничим для вас!
Створення таблиць для моделей в базі даних
Останній крок - додати нашу нову модель до нашої бази даних. Спочатку потрібно повідомити Django, що змінилась наша модель (ми щойно створили її!). Наберіть python manage.py makemigrations blog
. Це буде виглядати так:
(myvenv) ~/djangogirls$ python manage.py makemigrations blog
Migrations for 'blog':
0001_initial.py:
- Create model Post
Django підготував для нас файл перенесення, який ми повинні тепер застосувати до нашої бази даних. Наберіть python manage.py migrate blog
, на виході отримаємо:
(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
Ура! Наша модель допису Post тепер знаходиться у нашій базі даних. Було б добре побачити її, правда ж? Для цього перейдемо до наступного розділу!