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 тепер знаходиться у нашій базі даних. Було б добре побачити її, правда ж? Для цього перейдемо до наступного розділу!

results matching ""

    No results matching ""