Skip to content

Commit

Permalink
Add missing admin filter and fix model indexes (typeddjango#149)
Browse files Browse the repository at this point in the history
Hello, 

this PR actually makes two changes:

- add the missing `EmptyFieldListFilter`.
- fix the model `Index` class which also accepts positional parameters.

I am not sure if this is the right way to contribute to this repository.

- Is it ok to submit both changes in a single PR?
- How can I be sure everything is working fine? (a.k.a. tests)
  • Loading branch information
duilio authored Jan 7, 2023
1 parent 72b6ec5 commit 6b49bed
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 3 deletions.
5 changes: 5 additions & 0 deletions django-stubs/contrib/admin/filters.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,8 @@ class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
lookup_val_isnull: None
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]]: ...
7 changes: 6 additions & 1 deletion django-stubs/db/models/indexes.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ from typing import Any, List, Optional, Sequence, Tuple, Type
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from django.db.backends.ddl_references import Statement
from django.db.models.base import Model
from django.db.models.expressions import BaseExpression, Combinable
from django.db.models.query_utils import Q

class Index:
Expand All @@ -15,15 +16,19 @@ class Index:
db_tablespace: Optional[str] = ...
opclasses: Sequence[str] = ...
condition: Optional[Q] = ...
expressions: Sequence[BaseExpression | Combinable] = ...

def __init__(
self,
*,
*expressions: BaseExpression | Combinable | str,
fields: Sequence[str] = ...,
name: Optional[str] = ...,
db_tablespace: Optional[str] = ...,
opclasses: Sequence[str] = ...,
condition: Optional[Q] = ...
) -> None: ...
@property
def contains_expressions(self) -> bool: ...
def check_name(self) -> List[str]: ...
def create_sql(
self,
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/urls/conf.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ from ..conf.urls import IncludedURLConf
from ..http.response import HttpResponseBase
from .resolvers import URLPattern, URLResolver

_ResponseType = Union[HttpResponseBase, Coroutine[Any, Any, HttpResponseBase], Coroutine[Any, Any, None]]
_ResponseType = Union[
HttpResponseBase, Coroutine[Any, Any, HttpResponseBase], Coroutine[Any, Any, None]
]

def include(
arg: Any, namespace: Optional[str] = ...
Expand Down
4 changes: 3 additions & 1 deletion django-stubs/utils/html.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ def json_script(value: Any, element_id: str) -> SafeText: ...
def conditional_escape(text: Any) -> str: ...
def format_html(format_string: str, *args: Any, **kwargs: Any) -> SafeText: ...
def format_html_join(
sep: str, format_string: str, args_generator: Union[Iterable[Any], Iterable[Tuple[str]]]
sep: str,
format_string: str,
args_generator: Union[Iterable[Any], Iterable[Tuple[str]]],
) -> SafeText: ...
def linebreaks(value: Any, autoescape: bool = ...) -> str: ...

Expand Down
16 changes: 16 additions & 0 deletions tests/trout/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.contrib import admin

from .models import IndexModel


@admin.register(IndexModel)
class IndexModelAdmin(admin.ModelAdmin[IndexModel]):
list_display = [
"pub_date", "title", "author", "height", "weight",
]
list_filter = [
("author", admin.filters.EmptyFieldListFilter),
"pub_date",
]


25 changes: 25 additions & 0 deletions tests/trout/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Disable because pyright is not able to understand the Meta nested class override in models.
# pyright: reportIncompatibleVariableOverride=false

import sys
from collections import namedtuple
from datetime import time, timedelta
Expand All @@ -21,6 +24,7 @@
from django.core.cache import cache
from django.db import connection, connections, models
from django.db.backends.utils import CursorWrapper
from django.db.models.functions import Lower, Round
from django.db.models.manager import ManyToManyRelatedManager
from django.http.request import HttpRequest
from django.http.response import HttpResponse
Expand Down Expand Up @@ -1030,3 +1034,24 @@ def __init__(self, *args: Any, **kwargs: Any) -> None:


AuthUser.objects.create_superuser(username="foo", email=None, password=None)


class IndexModel(models.Model):
title = models.TextField()
author = models.ForeignKey[Optional[User]](User, on_delete=models.CASCADE, null=True)
pub_date = models.DateTimeField()
height = models.IntegerField()
weight = models.IntegerField()

class Meta:
# from: https://docs.djangoproject.com/en/3.2/ref/models/indexes/#expressions
indexes = [
models.Index(
Lower("title").desc(), "pub_date", name="lower_title_date_idx"
),
models.Index(
models.F("height") * models.F("weight"),
Round("weight"),
name="calc_idx",
),
]

0 comments on commit 6b49bed

Please sign in to comment.