РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
767 of 818 menu

Метод assertNumQueries

Метод assertNumQueries применяется в тестах Django для проверки того, что выполняется ожидаемое количество SQL-запросов. Он принимает ожидаемое число запросов и вызываемый объект или блок кода, который будет выполнен в контексте подсчёта запросов. Метод полезен для контроля производительности базы данных и предотвращения регрессий.

Синтаксис

self.assertNumQueries(num, func, *args, **kwargs)

Параметры метода:

  • num - ожидаемое количество выполняемых SQL-запросов
  • func - вызываемый объект (функция или метод), который будет выполнен
  • *args и **kwargs - аргументы, передаваемые вызываемому объекту

Также метод может использоваться как контекстный менеджер:

with self.assertNumQueries(num): # блок кода, где подсчитываются запросы

Пример

Рассмотрим простой пример использования метода для проверки количества запросов при получении списка статей:

from django.test import TestCase from myapp.models import Article, Category class ArticleTest(TestCase): @classmethod def setUpTestData(cls): category = Category.objects.create(name="Technology") for i in range(3): Article.objects.create( title=f"Article {i}", category=category ) def test_article_queryset(self): # Проверяем, что запрос выполняется один раз with self.assertNumQueries(1): articles = Article.objects.all() res = list(articles)

Пример

Пример использования метода для обнаружения проблемы N+1 запросов при обращении к связанным полям:

from django.test import TestCase from myapp.models import Article, Category class ArticleTest(TestCase): @classmethod def setUpTestData(cls): category = Category.objects.create(name="Technology") for i in range(3): Article.objects.create( title=f"Article {i}", category=category ) def test_article_without_prefetch(self): # Без prefetch_related будет N+1 запрос # 1 запрос для статей + 3 запроса для категорий = 4 запроса with self.assertNumQueries(4): articles = Article.objects.all() for article in articles: print(article.category.name) def test_article_with_prefetch(self): # С prefetch_related будет всего 2 запроса with self.assertNumQueries(2): articles = Article.objects.prefetch_related("category") for article in articles: print(article.category.name)

Пример

Использование метода с функцией, выполняющей сложные запросы и агрегации:

from django.test import TestCase from myapp.models import Article, Comment from django.db.models import Count class ArticleTest(TestCase): @classmethod def setUpTestData(cls): article = Article.objects.create( title="Test Article", status="published" ) for i in range(5): Comment.objects.create( article=article, text=f"Comment {i}", is_approved=i % 2 == 0 ) def test_article_with_annotate(self): # Проверяем количество запросов при использовании аннотаций def get_articles_with_count(): res = Article.objects.annotate( comment_count=Count("comments", filter=Q(comments__is_approved=True)) ).values("title", "comment_count") return list(res) # Ожидаем 1 запрос для аннотированной выборки with self.assertNumQueries(1): res = get_articles_with_count() print(res)

Результат выполнения кода:

[{'title': 'Test Article', 'comment_count': 3}]

Смотрите также

  • метод assertContains,
    который проверяет наличие содержимого в ответе
  • метод assertRedirects,
    который проверяет перенаправления в ответе
  • метод assertTemplateUsed,
    который проверяет использование шаблона
  • метод setUpTestData,
    который создаёт тестовые данные для класса
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить