87 lines
2.6 KiB
Python
87 lines
2.6 KiB
Python
from django.contrib.admin import filters
|
|
from django.db import models
|
|
from django.utils.http import urlencode
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
__all__ = ("DateFieldFilter", "DateTimeFieldFilter")
|
|
|
|
|
|
class DateFieldFilter(filters.FieldListFilter):
|
|
"""Display date input."""
|
|
|
|
template = "admin/aircox/filters/date_filter.html"
|
|
input_type = "date"
|
|
|
|
def __init__(self, field, request, params, model, model_admin, field_path):
|
|
self.field_generic = "%s__" % field_path
|
|
self.date_params = {
|
|
k: v for k, v in params.items() if k.startswith(self.field_generic)
|
|
}
|
|
|
|
exact_lookup = (
|
|
"date" if isinstance(field, models.DateTimeField) else "exact"
|
|
)
|
|
|
|
# links as: (label, param, input_type|None, value)
|
|
self.links = [
|
|
(_("Exact"), self.field_generic + exact_lookup, self.input_type),
|
|
(_("Since"), self.field_generic + "gte", self.input_type),
|
|
(_("Until"), self.field_generic + "lte", self.input_type),
|
|
]
|
|
if field.null:
|
|
self.links.insert(
|
|
0, (_("None"), self.field_generic + "isnull", None, "1")
|
|
)
|
|
|
|
self.query_attrs = {
|
|
k: v for k, v in request.GET.items() if k not in self.date_params
|
|
}
|
|
self.query_string = urlencode(self.query_attrs)
|
|
super().__init__(
|
|
field, request, params, model, model_admin, field_path
|
|
)
|
|
|
|
def expected_parameters(self):
|
|
return [link[1] for link in self.links]
|
|
|
|
def choices(self, changelist):
|
|
yield {
|
|
"label": _("Any"),
|
|
"type": None,
|
|
"query_string": self.query_string,
|
|
}
|
|
|
|
for link in self.links:
|
|
value = len(link) > 3 and link[3] or self.date_params.get(link[1])
|
|
yield {
|
|
"label": link[0],
|
|
"name": link[1],
|
|
"value": value,
|
|
"type": link[2],
|
|
"query_attrs": self.query_attrs,
|
|
"query_string": urlencode({link[1]: value})
|
|
+ "&"
|
|
+ self.query_string
|
|
if value
|
|
else self.query_string,
|
|
}
|
|
|
|
|
|
class DateTimeFieldFilter(DateFieldFilter):
|
|
"""Display datetime input."""
|
|
|
|
input_type = "datetime-local"
|
|
|
|
|
|
filters.FieldListFilter.register(
|
|
lambda f: isinstance(f, models.DateField),
|
|
DateFieldFilter,
|
|
take_priority=True,
|
|
)
|
|
|
|
filters.FieldListFilter.register(
|
|
lambda f: isinstance(f, models.DateTimeField),
|
|
DateTimeFieldFilter,
|
|
take_priority=True,
|
|
)
|