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