102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
|
from enum import Enum
|
||
|
from typing import Any
|
||
|
|
||
|
from django.db.models import (
|
||
|
BooleanField,
|
||
|
CharField,
|
||
|
FloatField,
|
||
|
IntegerField,
|
||
|
QuerySet,
|
||
|
TextField,
|
||
|
)
|
||
|
from django.http import HttpRequest
|
||
|
|
||
|
from common.components import *
|
||
|
from common.utils import get_field, get_model_by_string
|
||
|
|
||
|
filter_param_prefix = "f_"
|
||
|
|
||
|
|
||
|
class Modifier(Enum):
|
||
|
EQUALS = "__exact"
|
||
|
GT = "__gt"
|
||
|
LT = "__lt"
|
||
|
CONTAINS = "__contains"
|
||
|
REGEX = "__regex"
|
||
|
ISNULL = "__isnull"
|
||
|
BETWEEN = "__gt", "__lt"
|
||
|
|
||
|
|
||
|
def create_filter_form(model: str, fields: list[str]):
|
||
|
filter_model = get_model_by_string("games", model)
|
||
|
automatic_filter_form_parts = []
|
||
|
for field in fields:
|
||
|
html_field_name = f"{filter_param_prefix}{field}"
|
||
|
match get_field(filter_model, field):
|
||
|
case BooleanField():
|
||
|
automatic_filter_form_parts.append(
|
||
|
BooleanRadioFieldset(name=html_field_name, label=field)
|
||
|
)
|
||
|
case TextField():
|
||
|
pass
|
||
|
case CharField():
|
||
|
js = str
|
||
|
onclick_handler: js = """f_price_currency.disabled = true;"""
|
||
|
automatic_filter_form_parts.extend(
|
||
|
[
|
||
|
RadioFieldset(
|
||
|
name=f"{field}_switch",
|
||
|
label="Modifier",
|
||
|
radio_buttons=[
|
||
|
{
|
||
|
"label": "Equals",
|
||
|
"value": Modifier.EQUALS.value,
|
||
|
"onclick": onclick_handler,
|
||
|
},
|
||
|
{"label": "Contains", "value": Modifier.CONTAINS.value},
|
||
|
],
|
||
|
),
|
||
|
Input(
|
||
|
label=field,
|
||
|
id=html_field_name,
|
||
|
attributes=[
|
||
|
("name", html_field_name + str(Modifier.EQUALS.value))
|
||
|
],
|
||
|
),
|
||
|
]
|
||
|
)
|
||
|
case IntegerField():
|
||
|
pass
|
||
|
case FloatField():
|
||
|
html = Input(
|
||
|
label=field,
|
||
|
type="number",
|
||
|
id=html_field_name,
|
||
|
attributes=[("name", html_field_name)],
|
||
|
)
|
||
|
automatic_filter_form_parts.append(html)
|
||
|
case _:
|
||
|
print(f"Field type of {field} not handled yet.")
|
||
|
automatic_filter_form = Form(
|
||
|
children=[*automatic_filter_form_parts, SubmitButton("Apply")]
|
||
|
)
|
||
|
return automatic_filter_form
|
||
|
|
||
|
|
||
|
def apply_filters(request: HttpRequest, queryset: QuerySet[Any]):
|
||
|
for parameter in request.GET:
|
||
|
if parameter.startswith(filter_param_prefix):
|
||
|
field_name = parameter.removeprefix(filter_param_prefix)
|
||
|
field_value = request.GET.get(parameter)
|
||
|
if field_value == "":
|
||
|
continue
|
||
|
match field_value:
|
||
|
case "true":
|
||
|
field_value = True
|
||
|
case "false":
|
||
|
field_value = False
|
||
|
case _:
|
||
|
pass
|
||
|
queryset = queryset.filter(**{f"{field_name}": field_value})
|
||
|
return queryset
|