У цьому розділі ви дізнаєтесь як Django з'єднується із базою даних і зберігає в ній дані. Почнемо занурення!
A QuerySet є, по суті, списком об'єктів заданої Model. QuerySet дозволяє вам считувати дані з бази даних, а також фільтрувати і впорядковувати їх.
Найпростіше показати на прикладі. Давайте спробуємо?
Відкрийте консоль і наберіть команду:
(myvenv) ~/djangogirls$ python manage.py shell
Результат повинен бути наступним:
(InteractiveConsole)
>>>
Ви опинетесь в інтерактивній консолі Django. Це щось подібне на командний рядок із запитом в Python, але має додаткову магію Django:). Звичайно, тут ви також можете використовувати усі команди Python.
Давайте спробуємо спочатку вивести усі наші пости. Можна це зробити за допомогою наступної команди:
>>> Post.objects.all()
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'Post' is not defined
Ой! З'явилась помилка. Вона повідомляє нам, що немає ніяких постів. І це правильно, адже ми забули спочатку імпортувати їх!
>>> from blog.models import Post
Усе просто: імпортуємо модель Post з blog.models. Спробуємо вивести усі пости знову:
>>> Post.objects.all()
[]
В результаті отримаємо пустий список. Здається правильно, правда ж? Адже ми ще не додали жодного поста! То ж виправимо це.
Мова йдеться про те як створити об'єкт Post в базі даних:
>>> Post.objects.create(author=user, title='Sample title', text='Test')
Однак, маємо тут один пропущений елемент: користувач -user. Ми маємо передати екземпляр моделі User як автора. Як це зробити?
Спочатку імпортуємо модель User:
>>> from django.contrib.auth.models import User
Які користувачі присутні в нашій базі даних? Спробуймо це:
>>> User.objects.all()
[]
Жодного користувача! Давайте створимо одного:
>>> User.objects.create(username='ola')
<User: ola>
Яких користувачів ми маємо в нашій базі даних тепер? Спробуйте знову:
>>> User.objects.all()
[<User: ola>]
Круто! Давайте тепер отримаємо екземпляр користувача:
user = User.objects.get(username='ola')
Як бачимо, ми отримали користувача із іменем, що дорівнює 'ola'. Чудово! Звісно, ви мали б використовувати ваше ім'я.
Тепер зрештою можемо створити наш перший пост:
>>> Post.objects.create(author = user, title = 'Sample title', text = 'Test')
Урра! Бажаєте перевірити чи це працює?
>>> Post.objects.all()
[<Post: Sample title>]
А тепер можете трохи побавитися і пододавати більше постів щоб побачити як це працює. Додайте ще 2-3 поста і переходьте до наступної частини.
Великою частиною QuerySets є можливість фільтрувати запити до бази даних. Скажімо, ми хочемо відшукати усі пости, що мають автора ola. Будемо використовувати filter замість all в Post.objects.all(). В дужках ми вказуємо яким умовам повинен відповідати пост щоб завершити наш запит до бази даних. У нашому випадку автор є користувачем. В Django це можна відобразити так: author=user. Тепер наш шматок коду виглядає так:
>>> Post.objects.filter(author=user)
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
Чи, можливо, ми хочемо побачити усі пости, що містять слово 'title'в полі title?
>>> Post.objects.filter(title__contains='title')
[<Post: Sample title>, <Post: 4th title of post>]
Зауваження Тут використано два знаки підкреслювання (
_) міжtitleіcontains. Django ORM використовує цей синтаксис щоб відокремити імена полів ("title") і операції або фільтри ("contains"). Якщо ви раптом використаєте одне підкреслювання, то отримаєте помилку на кшталт "FieldError: Cannot resolve keyword title_contains".
Також можна отримати список усіх опублікованих постів. Зробимо це відфільтрувавши усі пости, що мають published_date`: задану в минулому часі
>>> from django.utils import timezone
>>> Post.objects.filter(published_date__lte=timezone.now())
[]
Нажаль, ще жоден наш пост не було опубліковано. Це можна змінити! Спершу отримаємо екземпляр поста, який ми хочемо опублікувати:
>>> post = Post.objects.get(id=1)
А далі опублікуємо його за допомогою нашого методу publish!
>>> post.publish()
А тепер спробуйте вивести список усіх опублікованих постів знову (натисніть 3 рази кнопку із стрілочкою вверх і після цього - enter):
>>> Post.objects.filter(published_date__lte=timezone.now())
[<Post: Sample title>]
QuerySets також дозволяє впорядковувати список об'єктів. Давайте спробуємо впорядкувати їх за параметром поля created_date:
>>> Post.objects.order_by('created_date')
[<Post: Sample title>, <Post: Post number 2>, <Post: My 3rd post!>, <Post: 4th title of post>]
Також можна здійснити впорядкування у зворотньому напрямку додавши - на початку:
>>> Post.objects.order_by('-created_date')
[<Post: 4th title of post>, <Post: My 3rd post!>, <Post: Post number 2>, <Post: Sample title>]
Клас! Тепер ви готові до наступної частини! Щоб закрити командну оболонку, наберіть:
>>> exit()
$