Фильтрация данных
В этой статье мы будем работать с моделями данных. Если вам не знаком этот термин, обратитесь к этой статье.
Итак, допустим, у вас есть модель Post
, которая описывает статью в блоге:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
is_deleted = models.BooleanField()
is_published = models.BooleanField()
У модели есть 2 интересных поля: is_deleted
и is_published
. Эти поля хранят 2 вида значений: либо True
, либо False
.
Фильтрация
На главной странице блога обычно показывают все опубликованные статьи. То есть не все, а те, у которых is_published == True
. Вот так можно получить их список:
posts = Post.objects.all()
published_posts = []
for post in posts:
if post.is_published:
published_posts.append(post)
Здесь мы достаём все посты из БД, а затем выбираем из них опубликованные.
Оказывается, в Django ORM можно сразу попросить прислать только опубликованные посты:
published_posts = Post.objects.filter(is_published=True)
is_published
— это название поля из модели данных Post
. В filter
можно указать название любого поля, из тех, что есть у модели данных:
deleted_posts = Post.objects.filter(is_deleted=True)
non_published_posts = Post.objects.filter(is_published=False)
non_deleted_posts = Post.objects.filter(is_deleted=False)
Если подходящие объекты не найдутся, вам вернётся пустой QuerySet. Он ведёт себя как пустой список.
Фильтрация по нескольким полям
Кажется, мы совсем забыли про поле is_deleted
. Если пост удалён, то его не нужно показывать на главной. Получается, нужно показать опубликованные посты и скрыть все удалённые. Можно сделать это так:
posts_to_show = Post.objects.filter(is_published=True, is_deleted=False)
filter умеет комбинировать несколько условий
Операции сравнения
Если пользователь ищет на вашем сайте статьи со словом "питон"
, то привычный способ фильтрации вам не поможет:
search_phrase = "питон"
searched_posts = Post.objects.filter(title="питон")
Здесь база данных будет искать посты, у которых заголовок в точности равен строке "питон"
. А нам нужны статьи со словом "питон"
в заголовке:
Питон для новичков
Джаваскрипт vs Питон
Питон в естественной среде обитания
Поможет операция сравнения contains
. Она позволит вам проверить, что заголовок содержит строку "питон"
:
searched_posts = Post.objects.filter(title__contains="питон")
Все операции сравнения начинаются с двух подчёркиваний и прямо “приписываются” к полям. Есть и другие операции сравнения, например, __gt
и __lt
:
__gt
— (greater then, в переводе, “больше чем”) проверяет, что поле больше, чем то, что передадут справа. Пример: filter(likes__gt=10)
— фильтруем посты, у которых больше 10 лайков.
__lt
— (less then, "меньше чем) аналогично, проверяет, что поле меньше.
Чтобы проверить условие “больше или равно”, есть операция сравнения __gte
, а “меньше ли равно” — __lte
.
Операции сравнения — фича Django ORM
Операции сравнения с двумя подчёкиваниями работают только в методах filter
, exclude
и get
из Django ORM и нигде больше. Не пытайтесь использовать это в работе с другими библиотеками и функциями, они не поймут.
Что читать дальше
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.