from typing import Any, Callable, Dict, Iterator, List, Optional, Tuple, Type

from django.contrib.admin.options import ModelAdmin
from django.db.models.base import Model
from django.db.models.fields import Field
from django.db.models.fields.related import RelatedField
from django.db.models.query import QuerySet
from django.http.request import HttpRequest

class ListFilter:
    title: str = ...
    template: str = ...
    used_parameters: Any = ...
    def __init__(
        self, request: HttpRequest, params: Dict[str, str], model: Type[Model], model_admin: ModelAdmin
    ) -> None: ...
    def has_output(self) -> bool: ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...
    def queryset(self, request: Any, queryset: QuerySet) -> Optional[QuerySet]: ...
    def expected_parameters(self) -> Optional[List[str]]: ...

class SimpleListFilter(ListFilter):
    parameter_name: str = ...
    lookup_choices: Any = ...
    def value(self) -> Optional[str]: ...
    def lookups(self, request: Any, model_admin: Any) -> List[Tuple[Any, str]]: ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class FieldListFilter(ListFilter):
    field: Field = ...
    field_path: str = ...
    title: str = ...
    def __init__(
        self,
        field: Field,
        request: HttpRequest,
        params: Dict[str, str],
        model: Type[Model],
        model_admin: ModelAdmin,
        field_path: str,
    ) -> None: ...
    @classmethod
    def register(cls, test: Callable, list_filter_class: Type[FieldListFilter], take_priority: bool = ...) -> None: ...
    @classmethod
    def create(
        cls,
        field: Field,
        request: HttpRequest,
        params: Dict[str, str],
        model: Type[Model],
        model_admin: ModelAdmin,
        field_path: str,
    ) -> FieldListFilter: ...

class RelatedFieldListFilter(FieldListFilter):
    used_parameters: Dict[Any, Any]
    lookup_kwarg: str = ...
    lookup_kwarg_isnull: str = ...
    lookup_val: Any = ...
    lookup_val_isnull: Any = ...
    lookup_choices: Any = ...
    lookup_title: str = ...
    title: str = ...
    empty_value_display: Any = ...
    @property
    def include_empty_choice(self) -> bool: ...
    def field_choices(
        self, field: RelatedField, request: HttpRequest, model_admin: ModelAdmin
    ) -> List[Tuple[str, str]]: ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class BooleanFieldListFilter(FieldListFilter):
    lookup_kwarg: str = ...
    lookup_kwarg2: str = ...
    lookup_val: Any = ...
    lookup_val2: Any = ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class ChoicesFieldListFilter(FieldListFilter):
    title: str
    used_parameters: Dict[Any, Any]
    lookup_kwarg: str = ...
    lookup_kwarg_isnull: str = ...
    lookup_val: Any = ...
    lookup_val_isnull: Any = ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class DateFieldListFilter(FieldListFilter):
    field_generic: Any = ...
    date_params: Any = ...
    lookup_kwarg_since: Any = ...
    lookup_kwarg_until: Any = ...
    links: Any = ...
    lookup_kwarg_isnull: Any = ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class AllValuesFieldListFilter(FieldListFilter):
    title: str
    used_parameters: Dict[Any, Any]
    lookup_kwarg: str = ...
    lookup_kwarg_isnull: str = ...
    lookup_val: Any = ...
    lookup_val_isnull: Any = ...
    empty_value_display: str = ...
    lookup_choices: QuerySet = ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...

class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
    lookup_kwarg: str
    lookup_kwarg_isnull: str
    lookup_val: Any
    lookup_val_isnull: Any
    title: str
    used_parameters: Dict[Any, Any]

class EmptyFieldListFilter(FieldListFilter):
    lookup_kwarg: str = ...
    lookup_val: Any = ...
    def choices(self, changelist: Any) -> Iterator[Dict[str, Any]]: ...
