Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
from typing import Any, TypedDict
from typing_extensions import assert_type

from django.db.models import Model, QuerySet
from django.http import HttpRequest
from django_filters.rest_framework import DjangoFilterBackend


class Product(Model): ...


class Customer(Model): ...


class ProductRow(TypedDict):
name: str


def check_filter_queryset(
request: HttpRequest,
view: object,
models: QuerySet[Product],
values: QuerySet[Product, ProductRow],
tuples: QuerySet[Product, tuple[int, str]],
dynamic_rows: QuerySet[Product, Any],
) -> None:
backend = DjangoFilterBackend()
assert_type(backend.filter_queryset(request, models, view), QuerySet[Product])
assert_type(backend.filter_queryset(request, values, view), QuerySet[Product, ProductRow])
assert_type(backend.filter_queryset(request, tuples, view), QuerySet[Product, tuple[int, str]])

assert_type(backend.filter_queryset(request, dynamic_rows, view), QuerySet[Product, Any])

filtered = backend.filter_queryset(request, values, view)
_wrong_model: QuerySet[Customer, ProductRow] = filtered # type: ignore[assignment]
_wrong_row: QuerySet[Product, str] = filtered # type: ignore[assignment]
10 changes: 8 additions & 2 deletions stubs/django-filter/django_filters/rest_framework/backends.pyi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Any, TypeAlias
from typing_extensions import TypeVar

from django.db.models import QuerySet
from django.db.models import Model, QuerySet
from django.http import HttpRequest
from django_filters.filterset import FilterSetMetaclass

Expand All @@ -9,6 +10,9 @@ from . import filterset
# APIView placeholder - djangorestframework is optional, so we use Any for compatibility
_APIView: TypeAlias = Any

_Model = TypeVar("_Model", bound=Model)
_Row = TypeVar("_Row", default=_Model)

class DjangoFilterBackend:
filterset_base: FilterSetMetaclass = ...
raise_exception: bool
Expand All @@ -25,5 +29,7 @@ class DjangoFilterBackend:
def get_filterset_kwargs(self, request: HttpRequest, queryset: QuerySet[Any], view: _APIView) -> dict[str, Any]: ...

# Filters any model type
def filter_queryset(self, request: HttpRequest, queryset: QuerySet[Any], view: _APIView) -> QuerySet[Any]: ...
def filter_queryset(
self, request: HttpRequest, queryset: QuerySet[_Model, _Row], view: _APIView
) -> QuerySet[_Model, _Row]: ...
def to_html(self, request: HttpRequest, queryset: QuerySet[Any], view: _APIView) -> str: ... # Renders form for any model
Loading