Django.db.models.QuerySet.filter: примеры (PYTHON)

Функция filter для QuerySet в Django на практике
Раздел: ORM Django, Базы данных
django.db.models.QuerySet.filter(*args, **kwargs): django.db.models.QuerySet

Описание метода filter

Метод filter() является ключевым способом фильтрации данных в Django ORM. Он применяется к объектам QuerySet и возвращает новый QuerySet, содержащий объекты, соответствующие заданным параметрам поиска.

Метод используется для извлечения подмножества записей из базы данных на основе условий. Все аргументы передаются как именованные параметры в формате поле__lookuptype=значение. Если передается несколько аргументов, они объединяются через логическое И (AND).

Основные виды lookups включают: exact (точное совпадение), iexact (без учета регистра), contains (содержит подстроку), in (вхождение в список), gt (больше), lt (меньше), range (диапазон), startswith (начинается с).

Возвращаемое значение - всегда объект QuerySet, даже если найдена только одна запись или ни одной. Пустой QuerySet возвращается при отсутствии совпадений.

Базовые примеры использования

Фильтрация по точному совпадению:

from myapp.models import Article
# Поиск статьи с id=5
articles = Article.objects.filter(id=5)
# Эквивалентно Article.objects.filter(id__exact=5)
<QuerySet [<Article: Пример статьи>]>

Фильтрация по нескольким условиям:

# Статьи с статусом 'published' и автором с id=1
articles = Article.objects.filter(status='published', author_id=1)
<QuerySet [<Article: Статья 1>, <Article: Статья 2>]>

Использование lookups:

# Статьи, опубликованные после 2023 года
articles = Article.objects.filter(published_date__year__gt=2023)
# Статьи, заголовок которых содержит 'Python'
articles = Article.objects.filter(title__contains='Python')
<QuerySet [<Article: Python в вебе>, <Article: Изучаем Python>]>

Похожие методы в Django ORM

exclude() - возвращает QuerySet с объектами, не соответствующими параметрам. Полезен для отрицательных условий.

Article.objects.exclude(status='draft')

get() - возвращает один объект, соответствующий условиям, но вызывает исключения, если объектов нет или их несколько. Используется, когда ожидается единственный результат.

article = Article.objects.get(id=1)

Q-объекты - позволяют строить сложные запросы с операторами ИЛИ (|) и отрицанием (~).

from django.db.models import Q
Article.objects.filter(Q(status='published') | Q(author_id=1))

Аналоги функции в других языках

JavaScript (с библиотекой):

// Использование lodash
const users = [
  {id: 1, active: true},
  {id: 2, active: false}
];
const activeUsers = _.filter(users, {active: true});
[{id: 1, active: true}]

PHP (Laravel Eloquent):

$users = User::where('active', 1)
            ->where('age', '>', 18)
            ->get();

SQL (язык запросов):

SELECT * FROM articles WHERE status = 'published' AND author_id = 1;

Java (Spring Data JPA):

public interface ArticleRepository extends JpaRepository {
    List
findByStatusAndAuthorId(String status, Long authorId); }

Частые ошибки

Опечатки в именах полей:

# Неверное имя поля 'titel' вместо 'title'
articles = Article.objects.filter(titel='Python')
FieldError: Cannot resolve keyword 'titel' into field.

Неправильное использование lookups:

# Пропущено двойное подчеркивание
articles = Article.objects.filter(title_contains='Python')
FieldError: Invalid lookup 'contains' for title...

Сравнение разных типов данных:

# Сравнение строки с числом
articles = Article.objects.filter(id='string')
ValueError: Field 'id' expected a number but got 'string'.

Изменения в последних версиях

В Django 4.0 появилась возможность использовать JSONField с более сложными фильтрами. В Django 3.2 улучшена производительность фильтрации по связанным полям. В версии 3.1 добавлена поддержка фильтрации с использованием выражений в правой части условия.

Начиная с Django 2.0, изменился синтаксис для фильтрации по связанным полям: вместо author__name используется тот же синтаксис, но с улучшенной поддержкой подзапросов.

Расширенные примеры

Фильтрация по связанным моделям:

Пример python
# Все статьи автора с именем 'Иван'
articles = Article.objects.filter(author__name='Иван')
# Все статьи из категории 'Программирование'
articles = Article.objects.filter(category__title='Программирование')

Использование F-выражений для сравнения полей:

Пример python
from django.db.models import F
# Статьи, где количество просмотров больше лайков
articles = Article.objects.filter(views__gt=F('likes'))

Комплексные запросы с Q-объектами:

Пример python
from django.db.models import Q
# Статьи опубликованные ИЛИ находящиеся в черновике у автора 1
articles = Article.objects.filter(
    Q(status='published') | 
    Q(status='draft', author_id=1)
)

Фильтрация по датам:

Пример python
import datetime
from django.utils import timezone
# Статьи за последние 7 дней
week_ago = timezone.now() - datetime.timedelta(days=7)
articles = Article.objects.filter(created_at__gte=week_ago)

Аннотации и агрегация в фильтрах:

Пример python
from django.db.models import Count
# Категории, содержащие более 10 статей
from blog.models import Category
categories = Category.objects.annotate(
    article_count=Count('articles')
).filter(article_count__gt=10)

Работа с JSONField:

Пример python
# Фильтрация по данным в JSONField
products = Product.objects.filter(
    metadata__brand='Apple',
    metadata__price__range=(1000, 5000)
)

питон django.db.models.QuerySet.filter function comments

En
Django.db.models.QuerySet.filter Return a new QuerySet with objects matching given parameters