Skip to content

Shortcut

lumi_filter.shortcut

Shortcut utilities for automatic model generation and request argument compatibility.

This module provides convenience utilities for automatically generating filter models from data sources and handling different request argument formats.

Classes:

Name Description
AutoQueryModel

Automatically generates filter models from data structure

Functions:

Name Description
compatible_request_args

Converts alternative syntax to standard lookup format

Supported Data Sources
  • Peewee ORM ModelSelect queries
  • Iterable data structures (list of dictionaries)
  • Nested dictionary structures with dot notation support
Alternative Syntax Mappings
  • == -> (exact match)
  • != -> ! (not equal)
  • = -> __gte

  • <= -> __lte
  • -> __gt

  • < -> __lt
  • LIKE -> __in (contains)
  • ILIKE -> __iin (case-insensitive contains)

AutoQueryModel

Automatic query model generator.

This class automatically generates filter models based on the structure of the provided data source, supporting both Peewee ORM queries and iterable data structures.

Parameters:

Name Type Description Default
data

The data source to generate model from

required
request_args dict

Request arguments for filtering

required
Source code in lumi_filter/shortcut.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
class AutoQueryModel:
    """Automatic query model generator.

    This class automatically generates filter models based on the structure
    of the provided data source, supporting both Peewee ORM queries and
    iterable data structures.

    Args:
        data: The data source to generate model from
        request_args (dict): Request arguments for filtering
    """

    def __new__(cls, data, request_args):
        cls.data = data
        cls.request_args = request_args
        attrs = {}
        if isinstance(cls.data, peewee.ModelSelect):
            for node in cls.data.selected_columns:
                if isinstance(node, peewee.Field):
                    attrs[node.name] = pw_filter_mapping.get(node.__class__, FilterField)(source=node)
                elif isinstance(node, peewee.Alias) and isinstance(node.node, peewee.Field):
                    pw_field = node.node
                    attrs[node.name] = pw_filter_mapping.get(pw_field.__class__, FilterField)(source=pw_field)
                else:
                    logger.warning(
                        "Unsupported field type in AutoQuery: %s. Using default FilterField.",
                        type(node),
                    )
        elif isinstance(cls.data, Iterable):
            cls.data = list(cls.data)
            if not cls.data:
                raise ValueError("Data cannot be empty for AutoQuery.")
            # Check if first item is a dict
            if not isinstance(cls.data[0], dict):
                raise TypeError("Unsupported data type for AutoQuery")
            stack = [(cls.data[0], "")]
            while stack:
                current_dict, key_prefix = stack.pop()
                for key, value in current_dict.items():
                    new_key = f"{key_prefix}.{key}" if key_prefix else key
                    if isinstance(value, dict):
                        stack.append((value, new_key))
                    else:
                        attrs[new_key.replace(".", "_")] = pd_filter_mapping.get(type(value), FilterField)(
                            request_arg_name=new_key, source=new_key
                        )
        else:
            logger.error("Unsupported data type for AutoQuery: %s", type(cls.data))
            raise TypeError("Unsupported data type for AutoQuery")
        return type("dynamic_filter_model", (Model,), attrs)(data=data, request_args=request_args)

compatible_request_args(request_args)

Convert request arguments to compatible format.

This function converts request arguments from alternative syntax formats to the standard lookup expression format used by the filter system.

Parameters:

Name Type Description Default
request_args dict

Dictionary of request arguments in alternative format

required

Returns:

Name Type Description
dict

Dictionary of converted request arguments

Raises:

Type Description
ValueError

If unsupported lookup expression is encountered

Source code in lumi_filter/shortcut.py
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
def compatible_request_args(request_args):
    """Convert request arguments to compatible format.

    This function converts request arguments from alternative syntax formats
    to the standard lookup expression format used by the filter system.

    Args:
        request_args (dict): Dictionary of request arguments in alternative format

    Returns:
        dict: Dictionary of converted request arguments

    Raises:
        ValueError: If unsupported lookup expression is encountered
    """
    ret = {}
    map = {
        "==": "",
        "!=": "!",
        ">=": "gte",
        "<=": "lte",
        ">": "gt",
        "<": "lt",
        "LIKE": "in",
        "ILIKE": "iin",
    }
    for key, value in request_args.items():
        key_part, lookup_expr = key.split("(", 1)
        lookup_expr = lookup_expr[:-1]
        if lookup_expr not in map:
            raise ValueError(f"Unsupported lookup expression: {lookup_expr}")

        mapped_expr = map[lookup_expr]
        if mapped_expr == "!":
            ret[f"{key_part}!"] = value
        elif mapped_expr == "":
            ret[key_part] = value
        elif mapped_expr in ["in", "iin"]:
            ret[f"{key_part}__{mapped_expr}"] = value[1:-1] if len(value) > 2 else value
        else:
            ret[f"{key_part}__{mapped_expr}"] = value
    return ret