mirror of
https://github.com/davidhalter/typeshed.git
synced 2026-05-06 21:43:59 +08:00
[django-filter] Add type stubs (#14540)
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
SECRET_KEY = "1"
|
||||
|
||||
INSTALLED_APPS = (
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sites",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.admin.apps.SimpleAdminConfig",
|
||||
"django.contrib.staticfiles",
|
||||
"django.contrib.auth",
|
||||
"django_filters",
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
# Iterator class attributes: Runtime behavior differs due to Django 5.0 compatibility logic in choice setters
|
||||
django_filters.fields.ChoiceField.iterator
|
||||
django_filters.fields.ModelChoiceField.iterator
|
||||
django_filters.fields.ModelMultipleChoiceField.iterator
|
||||
django_filters.fields.MultipleChoiceField.iterator
|
||||
|
||||
# Lookup NamedTuple: Parameter name mismatch between inferred stub and runtime
|
||||
django_filters.fields.Lookup.__new__
|
||||
django_filters.fields.Lookup.__doc__
|
||||
|
||||
# ChoiceIteratorMixin.choices: Cannot define choices property due to incompatibility with base class ChoiceField
|
||||
django_filters.fields.ChoiceIteratorMixin.choices
|
||||
@@ -0,0 +1,7 @@
|
||||
version = "25.1.*"
|
||||
upstream_repository = "https://github.com/carltongibson/django-filter/"
|
||||
requires = ["django-stubs"]
|
||||
|
||||
[tool.stubtest]
|
||||
mypy_plugins = ["mypy_django_plugin.main"]
|
||||
mypy_plugins_config = {"django-stubs" = {"django_settings_module" = "@tests.django_settings"}}
|
||||
@@ -0,0 +1,10 @@
|
||||
from typing import Final
|
||||
|
||||
from .filters import *
|
||||
from .filterset import FilterSet as FilterSet, UnknownFieldBehavior as UnknownFieldBehavior
|
||||
|
||||
__version__: Final[str]
|
||||
|
||||
def parse_version(version: str) -> tuple[str | int]: ...
|
||||
|
||||
VERSION: tuple[str | int, ...]
|
||||
@@ -0,0 +1 @@
|
||||
def is_crispy() -> bool: ...
|
||||
@@ -0,0 +1,17 @@
|
||||
from _typeshed import Unused
|
||||
from typing import Any
|
||||
|
||||
DEFAULTS: dict[str, Any] # Configuration values can be strings, booleans, callables, etc.
|
||||
DEPRECATED_SETTINGS: list[str]
|
||||
|
||||
def is_callable(value: Any) -> bool: ... # Accepts any value to test if it's callable
|
||||
|
||||
class Settings:
|
||||
# Setting values can be of any type, so getter and setter methods return/accept Any
|
||||
def __getattr__(self, name: str) -> Any: ... # Returns setting values of various types
|
||||
def get_setting(self, setting: str) -> Any: ... # Setting values vary by configuration option
|
||||
def change_setting(
|
||||
self, setting: str, value: Any, enter: bool, **kwargs: Unused
|
||||
) -> None: ... # Accepts any setting value type
|
||||
|
||||
settings: Settings
|
||||
@@ -0,0 +1,6 @@
|
||||
from typing import Any, Final
|
||||
|
||||
# String constant used to indicate all model fields should be included
|
||||
ALL_FIELDS: Final[str] = "__all__"
|
||||
# Collection of values considered empty by Django filters - tuple type allows various empty containers
|
||||
EMPTY_VALUES: Final[Any] = ...
|
||||
@@ -0,0 +1,8 @@
|
||||
from typing import Any
|
||||
|
||||
from django.core.exceptions import FieldError
|
||||
from django.db import models
|
||||
|
||||
class FieldLookupError(FieldError):
|
||||
# Field type params are runtime-determined
|
||||
def __init__(self, model_field: models.Field[Any, Any], lookup_expr: str) -> None: ...
|
||||
@@ -0,0 +1,100 @@
|
||||
from collections.abc import Sequence
|
||||
from typing import Any, NamedTuple
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
from django import forms
|
||||
|
||||
DJANGO_50: bool
|
||||
|
||||
# Ref: django-stubs/forms/fields.pyi
|
||||
# Problem: attribute `widget` is always of type `Widget` after field instantiation.
|
||||
# However, on class level it can be set to `Type[Widget]` too.
|
||||
# If we annotate it as `Union[Widget, Type[Widget]]`, every code that uses field
|
||||
# instances will not typecheck.
|
||||
# If we annotate it as `Widget`, any widget subclasses that do e.g.
|
||||
# `widget = Select` will not typecheck.
|
||||
# `Any` gives too much freedom, but does not create false positives.
|
||||
_ClassLevelWidget: TypeAlias = Any
|
||||
|
||||
class RangeField(forms.MultiValueField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def __init__(
|
||||
self, fields: tuple[forms.Field, forms.Field] | None = None, *args: Any, **kwargs: Any
|
||||
) -> None: ... # Args/kwargs can be any field params, passes to parent
|
||||
def compress(self, data_list: list[Any] | None) -> slice | None: ... # Data list elements can be any field value type
|
||||
|
||||
class DateRangeField(RangeField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for parent
|
||||
def compress(self, data_list: list[Any] | None) -> slice | None: ... # Date values in list can be any date type
|
||||
|
||||
class DateTimeRangeField(RangeField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for parent
|
||||
|
||||
class IsoDateTimeRangeField(RangeField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for parent
|
||||
|
||||
class TimeRangeField(RangeField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for parent
|
||||
|
||||
class Lookup(NamedTuple):
|
||||
value: Any # Lookup values can be any filterable type
|
||||
lookup_expr: str
|
||||
|
||||
class LookupChoiceField(forms.MultiValueField):
|
||||
def __init__(
|
||||
self, field: forms.Field, lookup_choices: Sequence[tuple[str, str]], *args: Any, **kwargs: Any
|
||||
) -> None: ... # Args/kwargs can be any field params, uses kwargs for empty_label
|
||||
def compress(self, data_list: list[Any] | None) -> Lookup | None: ... # Data list can contain any lookup components
|
||||
|
||||
class IsoDateTimeField(forms.DateTimeField):
|
||||
ISO_8601: str
|
||||
input_formats: list[str]
|
||||
def strptime(self, value: str, format: str) -> Any: ... # Returns datetime objects or parsing results
|
||||
|
||||
class BaseCSVField(forms.Field):
|
||||
base_widget_class: _ClassLevelWidget = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for widget config
|
||||
def clean(self, value: Any) -> Any: ... # Cleaned values can be any valid field type
|
||||
|
||||
class BaseRangeField(BaseCSVField):
|
||||
widget: _ClassLevelWidget = ...
|
||||
def clean(self, value: Any) -> Any: ... # Input and output values can be any range type
|
||||
|
||||
class ChoiceIterator:
|
||||
field: ChoiceField
|
||||
choices: Sequence[tuple[Any, str]] # Choice values can be any type (int, str, Model, etc.)
|
||||
def __init__(
|
||||
self, field: ChoiceField, choices: Sequence[tuple[Any, str]]
|
||||
) -> None: ... # Choice values can be any selectable type
|
||||
def __iter__(self) -> Any: ... # Iterator yields choice tuples with any value types
|
||||
def __len__(self) -> int: ...
|
||||
|
||||
class ModelChoiceIterator(forms.models.ModelChoiceIterator):
|
||||
def __iter__(self) -> Any: ... # Iterator yields choice tuples with any value types
|
||||
def __len__(self) -> int: ...
|
||||
|
||||
class ChoiceIteratorMixin:
|
||||
null_label: str | None
|
||||
null_value: Any # Null choice values can be any type (None, empty string, etc.)
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for null config
|
||||
|
||||
class ChoiceField(ChoiceIteratorMixin, forms.ChoiceField):
|
||||
iterator = ChoiceIterator
|
||||
empty_label: str | None
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params for label config
|
||||
|
||||
class MultipleChoiceField(ChoiceIteratorMixin, forms.MultipleChoiceField):
|
||||
iterator = ChoiceIterator
|
||||
empty_label: str | None
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any field params, sets empty_label
|
||||
|
||||
class ModelChoiceField(ChoiceIteratorMixin, forms.ModelChoiceField[Any]):
|
||||
iterator = ModelChoiceIterator
|
||||
def to_python(self, value: Any) -> Any: ... # Converts any input to Python model objects or values
|
||||
|
||||
class ModelMultipleChoiceField(ChoiceIteratorMixin, forms.ModelMultipleChoiceField[Any]):
|
||||
iterator = ModelChoiceIterator
|
||||
@@ -0,0 +1,234 @@
|
||||
from collections.abc import Callable
|
||||
from typing import Any
|
||||
|
||||
from django import forms
|
||||
from django.db.models import Q, QuerySet
|
||||
from django.forms import Field
|
||||
|
||||
from .fields import (
|
||||
BaseCSVField,
|
||||
BaseRangeField,
|
||||
DateRangeField,
|
||||
DateTimeRangeField,
|
||||
IsoDateTimeField,
|
||||
IsoDateTimeRangeField,
|
||||
LookupChoiceField,
|
||||
ModelChoiceField,
|
||||
ModelMultipleChoiceField,
|
||||
RangeField,
|
||||
TimeRangeField,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"AllValuesFilter",
|
||||
"AllValuesMultipleFilter",
|
||||
"BaseCSVFilter",
|
||||
"BaseInFilter",
|
||||
"BaseRangeFilter",
|
||||
"BooleanFilter",
|
||||
"CharFilter",
|
||||
"ChoiceFilter",
|
||||
"DateFilter",
|
||||
"DateFromToRangeFilter",
|
||||
"DateRangeFilter",
|
||||
"DateTimeFilter",
|
||||
"DateTimeFromToRangeFilter",
|
||||
"DurationFilter",
|
||||
"Filter",
|
||||
"IsoDateTimeFilter",
|
||||
"IsoDateTimeFromToRangeFilter",
|
||||
"LookupChoiceFilter",
|
||||
"ModelChoiceFilter",
|
||||
"ModelMultipleChoiceFilter",
|
||||
"MultipleChoiceFilter",
|
||||
"NumberFilter",
|
||||
"NumericRangeFilter",
|
||||
"OrderingFilter",
|
||||
"RangeFilter",
|
||||
"TimeFilter",
|
||||
"TimeRangeFilter",
|
||||
"TypedChoiceFilter",
|
||||
"TypedMultipleChoiceFilter",
|
||||
"UUIDFilter",
|
||||
]
|
||||
|
||||
class Filter:
|
||||
creation_counter: int
|
||||
field_class: type[Any] # Subclasses specify more specific field types
|
||||
field_name: str | None
|
||||
lookup_expr: str
|
||||
distinct: bool
|
||||
exclude: bool
|
||||
extra: dict[str, Any] # Field kwargs can include various types of parameters
|
||||
def __init__(
|
||||
self,
|
||||
field_name: str | None = None,
|
||||
lookup_expr: str | None = None,
|
||||
*,
|
||||
label: str | None = None,
|
||||
method: Callable[..., Any] | str | None = None, # Filter methods can return various types
|
||||
distinct: bool = False,
|
||||
exclude: bool = False,
|
||||
**kwargs: Any, # Field kwargs stored as extra (required, help_text, etc.)
|
||||
) -> None: ...
|
||||
def get_method(self, qs: QuerySet[Any]) -> Callable[..., QuerySet[Any]]: ... # Returns QuerySet filtering methods
|
||||
method: Callable[..., Any] | str | None # Custom filter methods return various types
|
||||
label: str | None # Filter label for display
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ... # Filter value can be any user input type
|
||||
|
||||
class CharFilter(Filter):
|
||||
field_class: type[forms.CharField]
|
||||
|
||||
class BooleanFilter(Filter):
|
||||
field_class: type[forms.NullBooleanField]
|
||||
|
||||
class ChoiceFilter(Filter):
|
||||
field_class: type[Any] # Base class for choice-based filters
|
||||
null_value: Any # Null value can be any type (None, empty string, etc.)
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for null_value config
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
|
||||
class TypedChoiceFilter(Filter):
|
||||
field_class: type[forms.TypedChoiceField]
|
||||
|
||||
class UUIDFilter(Filter):
|
||||
field_class: type[forms.UUIDField]
|
||||
|
||||
class MultipleChoiceFilter(Filter):
|
||||
field_class: type[Any] # Base class for multiple choice filters
|
||||
always_filter: bool
|
||||
conjoined: bool
|
||||
null_value: Any # Multiple choice null values vary by implementation
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for distinct, conjoined, null_value config
|
||||
def is_noop(self, qs: QuerySet[Any], value: Any) -> bool: ... # Value can be any filter input
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
def get_filter_predicate(self, v: Any) -> Q: ... # Predicate value can be any filter input type
|
||||
|
||||
class TypedMultipleChoiceFilter(MultipleChoiceFilter):
|
||||
field_class: type[forms.TypedMultipleChoiceField] # More specific than parent MultipleChoiceField
|
||||
|
||||
class DateFilter(Filter):
|
||||
field_class: type[forms.DateField]
|
||||
|
||||
class DateTimeFilter(Filter):
|
||||
field_class: type[forms.DateTimeField]
|
||||
|
||||
class IsoDateTimeFilter(DateTimeFilter):
|
||||
field_class: type[IsoDateTimeField]
|
||||
|
||||
class TimeFilter(Filter):
|
||||
field_class: type[forms.TimeField]
|
||||
|
||||
class DurationFilter(Filter):
|
||||
field_class: type[forms.DurationField]
|
||||
|
||||
class QuerySetRequestMixin:
|
||||
queryset: QuerySet[Any] | None
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for queryset config
|
||||
def get_request(self) -> Any: ... # Request can be HttpRequest or other request types
|
||||
def get_queryset(self, request: Any) -> QuerySet[Any]: ... # Request parameter accepts various request types
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
|
||||
class ModelChoiceFilter(QuerySetRequestMixin, ChoiceFilter):
|
||||
field_class: type[ModelChoiceField] # More specific than parent ChoiceField
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for empty_label config
|
||||
|
||||
class ModelMultipleChoiceFilter(QuerySetRequestMixin, MultipleChoiceFilter):
|
||||
field_class: type[ModelMultipleChoiceField] # More specific than parent MultipleChoiceField
|
||||
|
||||
class NumberFilter(Filter):
|
||||
field_class: type[forms.DecimalField]
|
||||
def get_max_validator(self) -> Any: ... # Validator can be various Django validator types
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
|
||||
class NumericRangeFilter(Filter):
|
||||
field_class: type[RangeField]
|
||||
lookup_expr: str
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
|
||||
class RangeFilter(Filter):
|
||||
field_class: type[RangeField]
|
||||
lookup_expr: str
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
|
||||
class DateRangeFilter(ChoiceFilter):
|
||||
choices: list[tuple[str, str]] | None
|
||||
filters: dict[str, Filter] | None
|
||||
def __init__(
|
||||
self, choices: list[tuple[str, str]] | None = None, filters: dict[str, Filter] | None = None, *args: Any, **kwargs: Any
|
||||
) -> None: ... # Uses args/kwargs for choice and filter configuration
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
|
||||
class DateFromToRangeFilter(RangeFilter):
|
||||
field_class: type[DateRangeField]
|
||||
|
||||
class DateTimeFromToRangeFilter(RangeFilter):
|
||||
field_class: type[DateTimeRangeField]
|
||||
|
||||
class IsoDateTimeFromToRangeFilter(RangeFilter):
|
||||
field_class: type[IsoDateTimeRangeField]
|
||||
|
||||
class TimeRangeFilter(RangeFilter):
|
||||
field_class: type[TimeRangeField]
|
||||
|
||||
class AllValuesFilter(ChoiceFilter):
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
|
||||
class AllValuesMultipleFilter(MultipleChoiceFilter):
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
|
||||
class BaseCSVFilter(Filter):
|
||||
base_field_class: type[BaseCSVField] = ...
|
||||
field_class: type[Any] # Base class for CSV-based filters
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for help_text and widget config
|
||||
|
||||
class BaseInFilter(BaseCSVFilter):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Sets lookup_expr and passes through
|
||||
|
||||
class BaseRangeFilter(BaseCSVFilter):
|
||||
base_field_class: type[BaseRangeField] = ...
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Sets lookup_expr and passes through
|
||||
|
||||
class LookupChoiceFilter(Filter):
|
||||
field_class: type[forms.CharField]
|
||||
outer_class: type[LookupChoiceField] = ...
|
||||
empty_label: str | None
|
||||
lookup_choices: list[tuple[str, str]] | None
|
||||
def __init__(
|
||||
self,
|
||||
field_name: str | None = None,
|
||||
lookup_choices: list[tuple[str, str]] | None = None,
|
||||
field_class: type[Field] | None = None,
|
||||
**kwargs: Any, # Handles empty_label and other field config
|
||||
) -> None: ...
|
||||
@classmethod
|
||||
def normalize_lookup(cls, lookup: Any) -> tuple[Any, str]: ...
|
||||
def get_lookup_choices(self) -> list[tuple[str, str]]: ...
|
||||
@property
|
||||
def field(self) -> Field: ...
|
||||
lookup_expr: str
|
||||
def filter(self, qs: QuerySet[Any], lookup: Any) -> QuerySet[Any]: ...
|
||||
|
||||
class OrderingFilter(BaseCSVFilter, ChoiceFilter):
|
||||
field_class: type[BaseCSVField] # Inherits CSV field behavior for comma-separated ordering
|
||||
descending_fmt: str
|
||||
param_map: dict[str, str] | None
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Uses kwargs for fields and field_labels config
|
||||
def get_ordering_value(self, param: str) -> str: ...
|
||||
def filter(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
@classmethod
|
||||
def normalize_fields(cls, fields: Any) -> list[str]: ...
|
||||
def build_choices(self, fields: Any, labels: dict[str, str] | None) -> list[tuple[str, str]]: ...
|
||||
|
||||
class FilterMethod:
|
||||
f: Filter
|
||||
def __init__(self, filter_instance: Filter) -> None: ...
|
||||
def __call__(self, qs: QuerySet[Any], value: Any) -> QuerySet[Any]: ...
|
||||
@property
|
||||
def method(self) -> Callable[..., Any]: ...
|
||||
@@ -0,0 +1,85 @@
|
||||
from collections import OrderedDict
|
||||
from enum import Enum
|
||||
from typing import Any, ClassVar
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Model, QuerySet
|
||||
from django.forms import Form
|
||||
from django.http import HttpRequest, QueryDict
|
||||
|
||||
from .filters import Filter
|
||||
|
||||
def remote_queryset(field: models.Field[Any, Any]) -> QuerySet[Any]: ... # Field type params vary by model definition
|
||||
|
||||
class UnknownFieldBehavior(Enum):
|
||||
RAISE = "raise"
|
||||
WARN = "warn"
|
||||
IGNORE = "ignore"
|
||||
|
||||
class FilterSetOptions:
|
||||
model: type[Model] | None
|
||||
fields: list[str] | dict[str, list[str]] | str | None
|
||||
exclude: list[str] | None
|
||||
filter_overrides: dict[type[models.Field[Any, Any]], dict[str, Any]] # Field override mapping
|
||||
form: type[Form]
|
||||
unknown_field_behavior: UnknownFieldBehavior
|
||||
def __init__(self, options: Any | None = None) -> None: ... # Meta options can be various configuration types
|
||||
|
||||
class FilterSetMetaclass(type):
|
||||
# Class attrs vary by definition
|
||||
def __new__(cls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> FilterSetMetaclass: ...
|
||||
|
||||
# Class attrs vary by definition
|
||||
@classmethod
|
||||
def get_declared_filters(cls, bases: tuple[type, ...], attrs: dict[str, Any]) -> OrderedDict[str, Filter]: ...
|
||||
|
||||
# Django field types vary widely - Any allows mapping all field types to their filters
|
||||
FILTER_FOR_DBFIELD_DEFAULTS: dict[type[models.Field[Any, Any]], dict[str, Any]]
|
||||
|
||||
class BaseFilterSet:
|
||||
FILTER_DEFAULTS: ClassVar[dict[type[models.Field[Any, Any]], dict[str, Any]]] = ... # Field type mapping
|
||||
is_bound: bool
|
||||
base_filters: OrderedDict[str, Filter]
|
||||
declared_filters: OrderedDict[str, Filter]
|
||||
data: QueryDict | dict[str, Any] | None # Filter input data values vary
|
||||
queryset: QuerySet[Any] | None # Base queryset for any model type
|
||||
request: HttpRequest | None
|
||||
form_prefix: str | None
|
||||
filters: OrderedDict[str, Filter]
|
||||
def __init__(
|
||||
self,
|
||||
data: QueryDict | dict[str, Any] | None = None, # Filter data values vary
|
||||
queryset: QuerySet[Any] | None = None, # Base queryset for any model
|
||||
*,
|
||||
request: HttpRequest | None = None,
|
||||
prefix: str | None = None,
|
||||
) -> None: ...
|
||||
def is_valid(self) -> bool: ...
|
||||
@property
|
||||
def errors(self) -> dict[str, list[str]]: ...
|
||||
def filter_queryset(self, queryset: QuerySet[Any]) -> QuerySet[Any]: ... # Works with any model type
|
||||
@property
|
||||
def qs(self) -> QuerySet[Any]: ... # Filtered queryset of any model
|
||||
def get_form_class(self) -> type[Form]: ...
|
||||
@property
|
||||
def form(self) -> Form: ...
|
||||
@classmethod
|
||||
def get_fields(cls) -> dict[str, models.Field[Any, Any]]: ... # Model fields have varying type params
|
||||
@classmethod
|
||||
def get_filter_name(cls, field_name: str, lookup_expr: str) -> str: ...
|
||||
@classmethod
|
||||
def get_filters(cls) -> OrderedDict[str, Filter]: ...
|
||||
@classmethod
|
||||
def handle_unrecognized_field(cls, field_name: str, message: str) -> None: ...
|
||||
@classmethod
|
||||
def filter_for_field(
|
||||
cls, field: models.Field[Any, Any], field_name: str, lookup_expr: str | None = None
|
||||
) -> Filter: ... # Accepts any Django field type
|
||||
@classmethod
|
||||
def filter_for_lookup(cls, field: models.Field[Any, Any], lookup_type: str) -> type[Filter]: ... # Field type varies by model
|
||||
|
||||
class FilterSet(BaseFilterSet, metaclass=FilterSetMetaclass): ...
|
||||
|
||||
def filterset_factory(
|
||||
model: type[Model], filterset: FilterSetMetaclass = ..., fields: list[str] | dict[str, list[str]] | str | None = None
|
||||
) -> type[FilterSet]: ...
|
||||
@@ -0,0 +1,3 @@
|
||||
from .backends import DjangoFilterBackend as DjangoFilterBackend
|
||||
from .filters import *
|
||||
from .filterset import FilterSet as FilterSet
|
||||
@@ -0,0 +1,30 @@
|
||||
from typing import Any
|
||||
from typing_extensions import TypeAlias
|
||||
|
||||
from django.db.models import QuerySet
|
||||
from django.http import HttpRequest
|
||||
from django_filters.filterset import FilterSetMetaclass
|
||||
|
||||
from . import filterset
|
||||
|
||||
# APIView placeholder - djangorestframework is optional, so we use Any for compatibility
|
||||
_APIView: TypeAlias = Any
|
||||
|
||||
class DjangoFilterBackend:
|
||||
filterset_base: FilterSetMetaclass = ...
|
||||
raise_exception: bool
|
||||
@property
|
||||
def template(self) -> str: ...
|
||||
|
||||
# Works with any model type
|
||||
def get_filterset(self, request: HttpRequest, queryset: QuerySet[Any], view: _APIView) -> filterset.FilterSet | None: ...
|
||||
|
||||
# Any model queryset
|
||||
def get_filterset_class(self, view: _APIView, queryset: QuerySet[Any] | None = None) -> type[filterset.FilterSet] | None: ...
|
||||
|
||||
# Kwargs vary by filterset
|
||||
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 to_html(self, request: HttpRequest, queryset: QuerySet[Any], view: _APIView) -> str: ... # Renders form for any model
|
||||
@@ -0,0 +1,71 @@
|
||||
from typing import Any
|
||||
|
||||
from ..filters import (
|
||||
AllValuesFilter,
|
||||
AllValuesMultipleFilter,
|
||||
BaseCSVFilter,
|
||||
BaseInFilter,
|
||||
BaseRangeFilter,
|
||||
BooleanFilter as _BaseBooleanFilter,
|
||||
CharFilter,
|
||||
ChoiceFilter,
|
||||
DateFilter,
|
||||
DateFromToRangeFilter,
|
||||
DateRangeFilter,
|
||||
DateTimeFilter,
|
||||
DateTimeFromToRangeFilter,
|
||||
DurationFilter,
|
||||
Filter,
|
||||
IsoDateTimeFilter,
|
||||
IsoDateTimeFromToRangeFilter,
|
||||
LookupChoiceFilter,
|
||||
ModelChoiceFilter,
|
||||
ModelMultipleChoiceFilter,
|
||||
MultipleChoiceFilter,
|
||||
NumberFilter,
|
||||
NumericRangeFilter,
|
||||
OrderingFilter,
|
||||
RangeFilter,
|
||||
TimeFilter,
|
||||
TimeRangeFilter,
|
||||
TypedChoiceFilter,
|
||||
TypedMultipleChoiceFilter,
|
||||
UUIDFilter,
|
||||
)
|
||||
|
||||
__all__ = [
|
||||
"AllValuesFilter",
|
||||
"AllValuesMultipleFilter",
|
||||
"BaseCSVFilter",
|
||||
"BaseInFilter",
|
||||
"BaseRangeFilter",
|
||||
"BooleanFilter",
|
||||
"CharFilter",
|
||||
"ChoiceFilter",
|
||||
"DateFilter",
|
||||
"DateFromToRangeFilter",
|
||||
"DateRangeFilter",
|
||||
"DateTimeFilter",
|
||||
"DateTimeFromToRangeFilter",
|
||||
"DurationFilter",
|
||||
"Filter",
|
||||
"IsoDateTimeFilter",
|
||||
"IsoDateTimeFromToRangeFilter",
|
||||
"LookupChoiceFilter",
|
||||
"ModelChoiceFilter",
|
||||
"ModelMultipleChoiceFilter",
|
||||
"MultipleChoiceFilter",
|
||||
"NumberFilter",
|
||||
"NumericRangeFilter",
|
||||
"OrderingFilter",
|
||||
"RangeFilter",
|
||||
"TimeFilter",
|
||||
"TimeRangeFilter",
|
||||
"TypedChoiceFilter",
|
||||
"TypedMultipleChoiceFilter",
|
||||
"UUIDFilter",
|
||||
]
|
||||
|
||||
# REST framework specific BooleanFilter that uses BooleanWidget by default
|
||||
class BooleanFilter(_BaseBooleanFilter):
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Accepts any filter initialization params
|
||||
@@ -0,0 +1,17 @@
|
||||
from collections import OrderedDict
|
||||
from typing import Any, ClassVar
|
||||
|
||||
from django.db import models
|
||||
from django.forms import Form
|
||||
from django_filters import filterset
|
||||
from django_filters.filters import Filter
|
||||
|
||||
# REST framework field mappings support all Django field types
|
||||
FILTER_FOR_DBFIELD_DEFAULTS: dict[type[models.Field[Any, Any]], dict[str, Any]]
|
||||
|
||||
class FilterSet(filterset.FilterSet):
|
||||
FILTER_DEFAULTS: ClassVar[dict[type[models.Field[Any, Any]], dict[str, Any]]] = ... # DRF field mappings
|
||||
base_filters: OrderedDict[str, Filter]
|
||||
declared_filters: OrderedDict[str, Filter]
|
||||
@property
|
||||
def form(self) -> Form: ...
|
||||
@@ -0,0 +1,36 @@
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Model
|
||||
|
||||
def deprecate(msg: str, level_modifier: int = 0) -> None: ...
|
||||
|
||||
class MigrationNotice(DeprecationWarning):
|
||||
url: str
|
||||
def __init__(self, message: str) -> None: ...
|
||||
|
||||
class RenameAttributesBase(type):
|
||||
renamed_attributes: tuple[tuple[str, str, DeprecationWarning], ...] = ()
|
||||
|
||||
# Class attrs vary by definition
|
||||
def __new__(metacls, name: str, bases: tuple[type, ...], attrs: dict[str, Any]) -> RenameAttributesBase: ...
|
||||
def get_name(metacls, name: str) -> str: ...
|
||||
def __getattr__(metacls, name: str) -> Any: ... # Attribute values vary by name and class
|
||||
def __setattr__(metacls, name: str, value: Any) -> None: ... # Attribute values can be any type
|
||||
|
||||
def try_dbfield(
|
||||
fn: Callable[[models.Field[Any, Any]], Any], field_class: type[models.Field[Any, Any]]
|
||||
) -> Any: ... # Generic field operation
|
||||
def get_all_model_fields(model: type[Model]) -> dict[str, models.Field[Any, Any]]: ... # Fields vary by model definition
|
||||
def get_model_field(model: type[Model], field_name: str) -> models.Field[Any, Any]: ... # Field type unknown at static time
|
||||
def get_field_parts(model: type[Model], field_name: str) -> list[models.Field[Any, Any]]: ... # Relationship fields vary
|
||||
def resolve_field(
|
||||
model_field: models.Field[Any, Any], lookup_expr: str
|
||||
) -> tuple[models.Field[Any, Any], str]: ... # Generic field resolution
|
||||
def handle_timezone(value: datetime, is_dst: bool | None = None) -> datetime: ...
|
||||
def verbose_field_name(model: type[Model], field_name: str) -> str: ...
|
||||
def verbose_lookup_expr(lookup_expr: str) -> str: ...
|
||||
def label_for_filter(model: type[Model], field_name: str, lookup_expr: str, exclude: bool = False) -> str: ...
|
||||
def translate_validation(error_dict: dict[str, list[str]]) -> dict[str, list[str]]: ...
|
||||
@@ -0,0 +1,38 @@
|
||||
from _typeshed import Unused
|
||||
from typing import Any
|
||||
|
||||
from django.db.models import Model, QuerySet
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.views.generic import View
|
||||
from django.views.generic.list import MultipleObjectMixin, MultipleObjectTemplateResponseMixin
|
||||
|
||||
from .constants import ALL_FIELDS
|
||||
from .filterset import FilterSet
|
||||
|
||||
class FilterMixin:
|
||||
filterset_class: type[FilterSet] | None
|
||||
filterset_fields = ALL_FIELDS
|
||||
strict: bool
|
||||
def get_filterset_class(self) -> type[FilterSet] | None: ...
|
||||
def get_filterset(self, filterset_class: type[FilterSet]) -> FilterSet: ...
|
||||
def get_filterset_kwargs(self, filterset_class: type[FilterSet]) -> dict[str, Any]: ... # Filterset init params vary
|
||||
def get_strict(self) -> bool: ...
|
||||
|
||||
class BaseFilterView(FilterMixin, MultipleObjectMixin[Any], View): # Generic model type
|
||||
filterset: FilterSet
|
||||
object_list: QuerySet[Any] # Filtered objects of any model type
|
||||
|
||||
def get(self, request: HttpRequest, *args: Unused, **kwargs: Unused) -> HttpResponse: ...
|
||||
|
||||
class FilterView(MultipleObjectTemplateResponseMixin, BaseFilterView):
|
||||
template_name_suffix: str
|
||||
|
||||
def object_filter(
|
||||
request: HttpRequest,
|
||||
model: type[Model] | None = None,
|
||||
queryset: QuerySet[Any] | None = None, # Base queryset for any model
|
||||
template_name: str | None = None,
|
||||
extra_context: dict[str, Any] | None = None, # Template context values vary
|
||||
context_processors: list[Any] | None = None, # Context processors vary by implementation
|
||||
filter_class: type[FilterSet] | None = None,
|
||||
) -> HttpResponse: ...
|
||||
@@ -0,0 +1,86 @@
|
||||
from collections.abc import Mapping, Sequence
|
||||
from typing import Any
|
||||
|
||||
from django import forms
|
||||
from django.http import QueryDict
|
||||
from django.utils.safestring import SafeString
|
||||
|
||||
class LinkWidget(forms.Widget):
|
||||
# Choice values can be any type (int, str, Model, etc.)
|
||||
choices: Sequence[tuple[Any, str]]
|
||||
# Choice values can be any selectable type
|
||||
def __init__(self, attrs: dict[str, Any] | None = None, choices: Sequence[tuple[Any, str]] = ()) -> None: ...
|
||||
data: QueryDict | dict[str, Any]
|
||||
# Return value depends on widget data type
|
||||
def value_from_datadict(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> Any: ...
|
||||
# Widget value and renderer can be any type, choices parameter combines with class choices
|
||||
def render( # type: ignore[override]
|
||||
self,
|
||||
name: str,
|
||||
value: Any,
|
||||
attrs: dict[str, Any] | None = None,
|
||||
choices: Sequence[tuple[Any, str]] = (),
|
||||
renderer: Any | None = None,
|
||||
) -> SafeString: ...
|
||||
# Choice values and selections can be any type
|
||||
def render_options(self, choices: Sequence[tuple[Any, str]], selected_choices: list[Any], name: str) -> str: ...
|
||||
# Selected choices and option values can be any type
|
||||
def render_option(self, name: str, selected_choices: list[Any], option_value: Any, option_label: str) -> str: ...
|
||||
def option_string(self) -> str: ...
|
||||
|
||||
class SuffixedMultiWidget(forms.MultiWidget):
|
||||
suffixes: list[str]
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ... # Args/kwargs can be any widget params for MultiWidget
|
||||
def suffixed(self, name: str, suffix: str) -> str: ...
|
||||
# Widget value and context can contain any data types
|
||||
def get_context(self, name: str, value: Any, attrs: dict[str, Any] | None) -> dict[str, Any]: ...
|
||||
# Returns list of any value types from widget data
|
||||
def value_from_datadict(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> list[Any]: ...
|
||||
# Widget data can contain any types
|
||||
def value_omitted_from_data(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> bool: ...
|
||||
def replace_name(self, output: str, index: int) -> str: ...
|
||||
# Decompresses any widget value into list of components
|
||||
def decompress(self, value: Any) -> list[Any] | None: ...
|
||||
|
||||
class RangeWidget(SuffixedMultiWidget):
|
||||
template_name: str
|
||||
suffixes: list[str]
|
||||
# Accepts any widget attribute types
|
||||
def __init__(self, attrs: dict[str, Any] | None = None) -> None: ...
|
||||
# Decompresses any range value into list components
|
||||
def decompress(self, value: Any) -> list[Any] | None: ...
|
||||
|
||||
class DateRangeWidget(RangeWidget):
|
||||
suffixes: list[str]
|
||||
|
||||
class LookupChoiceWidget(SuffixedMultiWidget):
|
||||
suffixes: list[str]
|
||||
# Decompresses any lookup choice value into components
|
||||
def decompress(self, value: Any) -> list[Any] | None: ...
|
||||
|
||||
class BooleanWidget(forms.Select):
|
||||
# Accepts any widget attribute types
|
||||
def __init__(self, attrs: dict[str, Any] | None = None) -> None: ...
|
||||
# Widget value and renderer can be any type
|
||||
def render(self, name: str, value: Any, attrs: dict[str, Any] | None = None, renderer: Any | None = None) -> SafeString: ...
|
||||
# Return value type depends on widget data
|
||||
def value_from_datadict(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> Any: ...
|
||||
|
||||
class BaseCSVWidget(forms.Widget):
|
||||
# Can be widget class or instance - __init__ converts to instance via instantiation or deepcopy
|
||||
surrogate: type[Any] = ...
|
||||
|
||||
# Args/kwargs can be any widget params for surrogate init
|
||||
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
|
||||
# CSV widget data can contain any types
|
||||
def value_from_datadict(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> list[str]: ...
|
||||
# Widget value and renderer can be any type
|
||||
def render(self, name: str, value: Any, attrs: dict[str, Any] | None = None, renderer: Any | None = None) -> SafeString: ...
|
||||
|
||||
class CSVWidget(BaseCSVWidget, forms.TextInput):
|
||||
# Args/kwargs can be any widget params, attrs for styling
|
||||
def __init__(self, *args: Any, attrs: dict[str, Any] | None = None, **kwargs: Any) -> None: ...
|
||||
|
||||
class QueryArrayWidget(BaseCSVWidget, forms.TextInput):
|
||||
# Query array widget data can contain any types
|
||||
def value_from_datadict(self, data: Mapping[str, Any], files: Mapping[str, Any], name: str) -> list[str]: ...
|
||||
Reference in New Issue
Block a user