CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-stubs-ext

Monkey-patching and extensions for django-stubs providing runtime type support for Django generic classes

Pending
Overview
Eval results
Files

queryset-types.mddocs/

QuerySet Type Aliases

Specialized type aliases for Django QuerySets that provide better type safety and IDE support when working with query results and values() calls. These aliases adapt their behavior based on whether type checking is active.

Capabilities

Generic QuerySet Alias

A flexible QuerySet type alias that works with any model type, providing proper generic support for type checkers while maintaining runtime compatibility.

QuerySetAny = QuerySet
"""
Type alias for generic QuerySet with any model.

In TYPE_CHECKING mode: Resolves to _QuerySetAny from django-stubs
At runtime: Standard Django QuerySet class
"""

Values QuerySet Alias

Specialized QuerySet type for handling values() query results with proper row typing support.

ValuesQuerySet = QuerySet
"""
Type alias for QuerySet with values() calls.

In TYPE_CHECKING mode: Resolves to _QuerySet[_T, _Row] from django-stubs  
At runtime: Standard Django QuerySet class
"""

Usage Examples

Basic QuerySet typing:

from django_stubs_ext import QuerySetAny
from django.db import models

class User(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()

# Type-safe QuerySet operations
def get_users() -> QuerySetAny:
    return User.objects.all()

users: QuerySetAny = get_users()
active_users: QuerySetAny = users.filter(is_active=True)

Values QuerySet typing:

from django_stubs_ext import ValuesQuerySet
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

# Type-safe values() operations
def get_product_summaries() -> ValuesQuerySet:
    return Product.objects.values('name', 'price')

summaries: ValuesQuerySet = get_product_summaries()
for summary in summaries:
    # Type checker understands this is a dict-like row
    print(f"{summary['name']}: ${summary['price']}")

Type Checking Behavior

The aliases provide different behavior in static analysis vs runtime:

import typing
from django.db.models.query import QuerySet

if typing.TYPE_CHECKING:
    # Static type checking mode
    from django.db.models.query import _QuerySetAny, _QuerySet, _Row, _T
    
    QuerySetAny = _QuerySetAny
    ValuesQuerySet = _QuerySet[_T, _Row]
else:
    # Runtime mode
    QuerySetAny = QuerySet
    ValuesQuerySet = QuerySet

This dual behavior ensures compatibility with both type checkers (which use the django-stubs type definitions) and runtime execution (which uses the actual Django QuerySet class).

Integration with Django ORM

These aliases work seamlessly with Django's ORM methods:

from django_stubs_ext import QuerySetAny, ValuesQuerySet
from django.db import models
from typing import Optional

class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published = models.BooleanField(default=False)

def search_posts(query: str) -> QuerySetAny:
    """Search for published blog posts."""
    return BlogPost.objects.filter(
        title__icontains=query,
        published=True
    )

def get_post_titles() -> ValuesQuerySet:
    """Get just the titles of published posts."""
    return BlogPost.objects.filter(published=True).values('title')

# Type-safe usage
results: QuerySetAny = search_posts("django")
first_post: Optional[BlogPost] = results.first()

titles: ValuesQuerySet = get_post_titles()
title_list: list = list(titles)

Types

import typing
from django.db.models.query import QuerySet

if typing.TYPE_CHECKING:
    from django.db.models.query import _QuerySetAny, _QuerySet, _Row, _T
    
    QuerySetAny = _QuerySetAny
    ValuesQuerySet = _QuerySet[_T, _Row]
else:
    QuerySetAny = QuerySet
    ValuesQuerySet = QuerySet

Install with Tessl CLI

npx tessl i tessl/pypi-django-stubs-ext

docs

index.md

model-annotations.md

monkey-patching.md

protocols.md

queryset-types.md

string-types.md

tile.json