【问题标题】:Build Django Query Dynamically based on kendo UI filter基于 kendo UI 过滤器动态构建 Django Query
【发布时间】:2022-01-07 06:18:54
【问题描述】:

我正在尝试根据用户过滤器查询数据库。我收到了来自剑道 UI 网格的以下输入。

{
   "filter":{
      "filters":[
         {
            "logic":"or",
            "filters":[
               {
                  "field":"aging",
                  "operator":"eq",
                  "value":24
               },
               {
                  "field":"aging",
                  "operator":"eq",
                  "value":13
               }
            ]
         },
         {
            "logic":"or",
            "filters":[
               {
                  "field":"follow_up_name",
                  "operator":"eq",
                  "value":"Call Insurance Provider"
               }
            ]
         },
         {
            "logic":"or",
            "filters":[
               {
                  "field":"patient_name",
                  "operator":"eq",
                  "value":"kartik"
               }
            ]
         },
         {
            "logic":"and",
            "filters":[
               {
                  "field":"created_date",
                  "operator":"eq",
                  "value":"2022-01-09T18:30:00.000Z"
               },
               {
                  "field":"created_date",
                  "operator":"gte",
                  "value":"2022-01-04T18:30:00.000Z"
               }
            ]
         },
         {
            "logic":"or",
            "filters":[
               {
                  "field":"follow_up_status",
                  "operator":"eq",
                  "value":"Open"
               }
            ]
         },
         {
            "logic":"or",
            "filters":[
               {
                  "field":"role_name",
                  "operator":"eq",
                  "value":"Pharmacist"
               }
            ]
         },
         {
            "logic":"or",
            "filters":[
               {
                  "field":"last_response",
                  "operator":"eq",
                  "value":"To-Patient"
               }
            ]
         }
      ],
      "logic":"and"
   },
   "skip":0,
   "take":10
}

基于上述数据,我需要“和”和“或”条件来动态构建查询。并将其传递给数据库。过滤器也可以包含多个列表。还希望使这些只能使用 UI 参数构建查询和返回的类通用。请提供解决方案。

【问题讨论】:

    标签: python-3.x django kendo-grid


    【解决方案1】:

    Q 对象在这里是你的朋友。

    from django.db.models import QuerySet, Q
    from functools import reduce
    
    def filter_rec(data: dict) -> Q:
        logic = data.get('logic', None)
        # Leaf node
        if logic is None:
            field = data['field']
            operator = data['operator']
            value = data['value']
            return Q(**{f'{field}__{operator}': value})
        # Node with children
        children = list()
        for item in data['filters']:
            child = filter_rec(child)
            children.append(child)
        if logic == 'and':
            query = reduce(lambda x, y: x & y, children)
        elif logic == 'or':
            query = reduce(lambda x, y: x | y, children)
        return query
    
    def kendo_filter(data: dict, qs: QuerySet) -> QuerySet:
        query = filter_rec(data['filter'])
        skip = data['skip']
        take = data['take']
        filtered_qs = qs.filter(query)
        paginated_qs = filtered_qs[skip:skip+take]
        return paginated_qs
    

    一般要点是这样的。由您来验证数据并进行错误处理。

    filter_rec(data['filter']) 为您的示例数据返回以下内容:

     <Q: (
        AND: 
            (OR: ('aging__eq', 24), ('aging__eq', 13)), 
            ('follow_up_name__eq', 'Call Insurance Provider'), 
            ('patient_name__eq', 'kartik'), 
            ('created_date__eq', '2022-01-09T18:30:00.000Z'), 
            ('created_date__gte', '2022-01-04T18:30:00.000Z'), 
            ('follow_up_status__eq', 'Open'), 
            ('role_name__eq', 'Pharmacist'), 
            ('last_response__eq', 'To-Patient')
    )>
    

    由于单个 OR 将按原样提升,而嵌套的 AND 将显示为单个级别,因此它似乎奏效了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多