or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdmodel-annotations.mdmonkey-patching.mdprotocols.mdqueryset-types.mdstring-types.md

queryset-types.mddocs/

0

# QuerySet Type Aliases

1

2

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.

3

4

## Capabilities

5

6

### Generic QuerySet Alias

7

8

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

9

10

```python { .api }

11

QuerySetAny = QuerySet

12

"""

13

Type alias for generic QuerySet with any model.

14

15

In TYPE_CHECKING mode: Resolves to _QuerySetAny from django-stubs

16

At runtime: Standard Django QuerySet class

17

"""

18

```

19

20

### Values QuerySet Alias

21

22

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

23

24

```python { .api }

25

ValuesQuerySet = QuerySet

26

"""

27

Type alias for QuerySet with values() calls.

28

29

In TYPE_CHECKING mode: Resolves to _QuerySet[_T, _Row] from django-stubs

30

At runtime: Standard Django QuerySet class

31

"""

32

```

33

34

### Usage Examples

35

36

Basic QuerySet typing:

37

38

```python

39

from django_stubs_ext import QuerySetAny

40

from django.db import models

41

42

class User(models.Model):

43

name = models.CharField(max_length=100)

44

email = models.EmailField()

45

46

# Type-safe QuerySet operations

47

def get_users() -> QuerySetAny:

48

return User.objects.all()

49

50

users: QuerySetAny = get_users()

51

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

52

```

53

54

Values QuerySet typing:

55

56

```python

57

from django_stubs_ext import ValuesQuerySet

58

from django.db import models

59

60

class Product(models.Model):

61

name = models.CharField(max_length=100)

62

price = models.DecimalField(max_digits=10, decimal_places=2)

63

64

# Type-safe values() operations

65

def get_product_summaries() -> ValuesQuerySet:

66

return Product.objects.values('name', 'price')

67

68

summaries: ValuesQuerySet = get_product_summaries()

69

for summary in summaries:

70

# Type checker understands this is a dict-like row

71

print(f"{summary['name']}: ${summary['price']}")

72

```

73

74

### Type Checking Behavior

75

76

The aliases provide different behavior in static analysis vs runtime:

77

78

```python

79

import typing

80

from django.db.models.query import QuerySet

81

82

if typing.TYPE_CHECKING:

83

# Static type checking mode

84

from django.db.models.query import _QuerySetAny, _QuerySet, _Row, _T

85

86

QuerySetAny = _QuerySetAny

87

ValuesQuerySet = _QuerySet[_T, _Row]

88

else:

89

# Runtime mode

90

QuerySetAny = QuerySet

91

ValuesQuerySet = QuerySet

92

```

93

94

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).

95

96

### Integration with Django ORM

97

98

These aliases work seamlessly with Django's ORM methods:

99

100

```python

101

from django_stubs_ext import QuerySetAny, ValuesQuerySet

102

from django.db import models

103

from typing import Optional

104

105

class BlogPost(models.Model):

106

title = models.CharField(max_length=200)

107

content = models.TextField()

108

published = models.BooleanField(default=False)

109

110

def search_posts(query: str) -> QuerySetAny:

111

"""Search for published blog posts."""

112

return BlogPost.objects.filter(

113

title__icontains=query,

114

published=True

115

)

116

117

def get_post_titles() -> ValuesQuerySet:

118

"""Get just the titles of published posts."""

119

return BlogPost.objects.filter(published=True).values('title')

120

121

# Type-safe usage

122

results: QuerySetAny = search_posts("django")

123

first_post: Optional[BlogPost] = results.first()

124

125

titles: ValuesQuerySet = get_post_titles()

126

title_list: list = list(titles)

127

```

128

129

## Types

130

131

```python { .api }

132

import typing

133

from django.db.models.query import QuerySet

134

135

if typing.TYPE_CHECKING:

136

from django.db.models.query import _QuerySetAny, _QuerySet, _Row, _T

137

138

QuerySetAny = _QuerySetAny

139

ValuesQuerySet = _QuerySet[_T, _Row]

140

else:

141

QuerySetAny = QuerySet

142

ValuesQuerySet = QuerySet

143

```