parmas to dict

This commit is contained in:
Aaron Kable
2026-01-08 20:11:40 +08:00
parent 7eb0a6c473
commit ad1c17a255

View File

@@ -13,81 +13,56 @@ from allianceauth.services.hooks import get_extension_logger
logger = get_extension_logger(__name__) logger = get_extension_logger(__name__)
class nested_param_dict(dict):
def __setitem__(self, item, value):
if "." in item:
head, path = item.split(".", 1)
obj = self.setdefault(head, nested_param_dict())
obj[path] = value
else:
super().__setitem__(item, value)
class DataTablesView(View): class DataTablesView(View):
model: Model = None model: Model = None
columns: List[tuple] = [] columns: list[tuple] = []
COL_SEARCH_REGEX = r"columns\[(?P<id>[0-9]{1,})\]\[search\]\[value\]"
COL_SEARCHABLE_REGEX = r"columns\[(?P<id>[0-9]{1,})\]\[searchable\]"
COL_SEARCHABLE_AS_REGEX_REGEX = r"columns\[(?P<id>[0-9]{1,})\]\[search\]\[regex\]"
COL_ORDERABLE_REGEX = r"columns\[(?P<id>[0-9]{1,})\]\[orderable\]"
search_regex: re.Pattern = None
searchable_regex: re.Pattern = None
searchable_as_regex_regex: re.Pattern = None
order_regex: re.Pattern = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.search_regex = re.compile(self.COL_SEARCH_REGEX)
self.searchable_regex = re.compile(self.COL_SEARCHABLE_REGEX)
self.searchable_as_regex_regex = re.compile(self.COL_SEARCHABLE_AS_REGEX_REGEX)
self.order_regex = re.compile(self.COL_ORDERABLE_REGEX)
def get_model_qs(self, request: HttpRequest, *args, **kwargs): def get_model_qs(self, request: HttpRequest, *args, **kwargs):
return self.model.objects return self.model.objects
def get_param(self, request: HttpRequest, key: str, cast=str, default=""): def filter_qs(self, table_conf: dict):
return cast(request.GET.get(key, default))
def filter_qs(self, search_string: str, column_conf: dict):
# Search # Search
filter_q = Q() filter_q = Q()
for id, c in column_conf.items(): for id, c in table_conf["columns"].items():
_c = self.columns[id][0] _c = self.columns[int(id)][0]
if c["searchable"] and len(_c) > 0: if c["searchable"] and len(_c) > 0:
if len(c["search"]) and len(_c): if len(c["search"]["value"]) and len(_c):
if c["regex"]: if c["search"]["regex"]:
filter_q |= Q(**{f'{_c}__iregex': c["search"]}) filter_q |= Q(**{f'{_c}__iregex': c["search"]["value"]})
else: else:
filter_q |= Q(**{f'{_c}__icontains': c["search"]}) filter_q |= Q(**{f'{_c}__icontains': c["search"]["value"]})
if len(search_string) > 0: if len(table_conf["search"]["value"]) > 0:
filter_q |= Q(**{f'{_c}__icontains': search_string}) filter_q |= Q(**{f'{_c}__icontains': table_conf["search"]["value"]})
return filter_q return filter_q
def get_columns_config(self, get: dict): def get_table_config(self, get: dict):
columns = defaultdict( _cols = nested_param_dict()
lambda: { for c, v in get.items():
"searchable": False, _keys = [_k for _k in c.replace("]", "").split("[")]
"orderable": False, _cols[".".join(_keys)] = v
"regex": False, return _cols
"search": ""
}
)
for c in get:
_r = self.search_regex.findall(c)
if _r:
columns[int(_r[0])]["search"] = get[c]
_r_s = self.searchable_regex.findall(c)
if _r_s:
columns[int(_r_s[0])]["searchable"] = get[c] == "true"
_r_s_r = self.searchable_as_regex_regex.findall(c)
if _r_s_r:
columns[int(_r_s_r[0])]["regex"] = get[c] == "true"
_r_o = self.order_regex.findall(c)
if _r_o:
columns[int(_r_o[0])]["orderable"] = get[c] == "true"
return columns
def order_str(self, order_col, order_dir, column_conf: dict): def get_order(self, table_conf: dict):
order = "" order = []
_o = column_conf[order_col] for oc, od in table_conf["order"].items():
if _o["orderable"]: _c = table_conf["columns"][od["column"]]
if order_dir == 'desc': if _c["orderable"]:
order = '-' + self.columns[order_col][0] if od["column"] == 'desc':
else: order.append('-' + self.columns[int(od["column"])][0])
order = self.columns[order_col][0] else:
order.append(self.columns[int(od["column"])][0])
return order return order
def render_template(self, request: HttpRequest, template: str, ctx: dict): def render_template(self, request: HttpRequest, template: str, ctx: dict):
@@ -102,30 +77,26 @@ class DataTablesView(View):
) )
def get(self, request: HttpRequest, *args, **kwargs): def get(self, request: HttpRequest, *args, **kwargs):
table_conf = self.get_table_config(request.GET)
# Get all our Params out of GET draw = int(table_conf["draw"])
length = self.get_param(request, "length", int) start = int(table_conf["start"])
start = self.get_param(request, "start", int) length = int(table_conf["length"])
search_string = self.get_param(request, "search[value]")
order_col = self.get_param(request, "order[0][column]", int, 0)
order_dir = self.get_param(request, "order[0][dir]")
draw = self.get_param(request, "draw", int)
limit = start + length limit = start + length
column_conf = self.get_columns_config(request.GET)
# Searches # Searches
filter_q = Q() | self.filter_qs(search_string, column_conf) filter_q = Q() | self.filter_qs(table_conf)
# Build response rows # Build response rows
items = [] items = []
qs = self.get_model_qs(request, *args, **kwargs).filter(filter_q).order_by() qs = self.get_model_qs(
request,
# Apply ordering *args,
order = self.order_str(order_col, order_dir, column_conf) **kwargs
if order != "": ).filter(
qs = qs.order_by(order) filter_q
).order_by(
*self.get_order(table_conf)
)
# build output # build output
for row in qs[start:limit]: for row in qs[start:limit]: