Django · Query Evaluation
Django QuerySets: Choose exists(), count() or Loaded Rows Deliberately
Match existence checks, counts and row loading to what a response actually needs, then reuse fetched results.

A dashboard may need both a list of records and a count. Choosing the database operation depends on whether those rows will be displayed.
Choose one path
If an endpoint only needs to answer whether published articles exist, use Article.objects.filter(is_published=True).exists(). If it only needs a total, use count(). Neither task needs a collection of model objects.
When a page will render the records anyway, keep one queryset and reuse its results:
articles = Article.objects.filter(is_published=True)
rows = list(articles)
total = len(rows)
This evaluates the queryset and keeps the fetched rows available for rendering. Calling exists(), then count(), then iterating the unevaluated queryset can add database trips for information the loaded rows already provide.
Keep the scope deliberate
Materializing every article is unsuitable for an unbounded archive. Paginate first; a page count and a full collection count answer different questions. Use a separate count when the interface needs the total across all pages.
Measure the real view
Check query counts and memory with representative data before changing code. Choose the smallest operation that serves the response, and reuse loaded results within that request.