diff --git a/django-stubs/db/models/__init__.pyi b/django-stubs/db/models/__init__.pyi index b829bd8e3..d922fb609 100644 --- a/django-stubs/db/models/__init__.pyi +++ b/django-stubs/db/models/__init__.pyi @@ -1,6 +1,15 @@ from .base import Model as Model -from .aggregates import Aggregate as Aggregate, Sum as Sum, Variance as Variance, Count as Count, Max as Max +from .aggregates import ( + Aggregate as Aggregate, + Avg as Avg, + Count as Count, + Max as Max, + Min as Min, + StdDev as StdDev, + Sum as Sum, + Variance as Variance, +) from .fields import ( AutoField as AutoField, @@ -47,7 +56,12 @@ from .deletion import ( PROTECT as PROTECT, ) -from .query import QuerySet as QuerySet, RawQuerySet as RawQuerySet +from .query import ( + Prefetch as Prefetch, + QuerySet as QuerySet, + RawQuerySet as RawQuerySet, + prefetch_related_objects as prefetch_related_objects, +) from .query_utils import Q as Q, FilteredRelation as FilteredRelation diff --git a/django-stubs/db/models/query.pyi b/django-stubs/db/models/query.pyi index f7d0902e2..23ab5cfbc 100644 --- a/django-stubs/db/models/query.pyi +++ b/django-stubs/db/models/query.pyi @@ -143,5 +143,17 @@ class RawQuerySet(Iterable[_T], Sized): def resolve_model_init_order(self) -> Tuple[List[str], List[int], List[Tuple[str, int]]]: ... def using(self, alias: Optional[str]) -> RawQuerySet[_T]: ... +class Prefetch(object): + def __init__(self, lookup: str, queryset: Optional[QuerySet] = None, to_attr: Optional[str] = None) -> None: ... + def __getstate__(self) -> Dict[str, Any]: ... + def add_prefix(self, prefix: str) -> None: ... + def get_current_prefetch_to(self, level: int) -> str: ... + def get_current_to_attr(self, level: int) -> Tuple[str, str]: ... + def get_current_queryset(self, level) -> Optional[QuerySet]: ... + +def prefetch_related_objects(model_instances: Iterable[_T], *related_lookups: Union[str, Prefetch]) -> None: ... +def get_prefetcher(instance: _T, through_attr: str, to_attr: str) -> Tuple[Any, Any, bool, bool]: ... + +class ModelIterable(Iterable[_T]): ... class InstanceCheckMeta(type): ... class EmptyQuerySet(metaclass=InstanceCheckMeta): ... diff --git a/scripts/typecheck_tests.py b/scripts/typecheck_tests.py index 1b10eb7ba..7f2720491 100644 --- a/scripts/typecheck_tests.py +++ b/scripts/typecheck_tests.py @@ -55,6 +55,8 @@ 'Argument 1 to "bytes"', '"full_clean" of "Model" does not return a value', '"object" not callable', + 'Item "GenericForeignKey" of "Union[GenericForeignKey, Model, None]" has no attribute "read_by"', + 'Item "Model" of "Union[GenericForeignKey, Model, None]" has no attribute "read_by"', re.compile('Cannot determine type of \'(objects|stuff|specimens|normal_manager)\''), re.compile(r'"Callable\[\[(Any(, )?)+\], Any\]" has no attribute'), re.compile(r'"HttpResponseBase" has no attribute "[A-Za-z_]+"'), @@ -215,9 +217,9 @@ 'or_lookups', 'order_with_respect_to', 'ordering', + 'prefetch_related', 'pagination', # TODO: 'postgres_tests', - # TODO: 'prefetch_related', 'project_template', 'properties', 'proxy_model_inheritance',