Search code examples
pythondjangodictionarydatatables

How to convert query string parameters from Datatables.js, like columns[0][name] into an object in Python/Django?


I'm using DataTables.js and trying to hook up server-side processing. I'm using Django on the server.

Currently, the data to Django looks like:

{'draw': '1',
 'columns[0][data]': '0',
 'columns[0][name]': 'Brand',
 'columns[0][searchable]': 'true',
 'columns[0][orderable]': 'true',
 'columns[0][search][value]': '',
 'columns[0][search][regex]': 'false',
 'columns[1][data]': '1',
 'columns[1][name]': 'Sku',
 'columns[1][searchable]': 'true',
 'columns[1][orderable]': 'true',
 'columns[1][search][value]': '',
 'columns[1][search][regex]': 'false',
 'columns[2][data]': '2',
 'columns[2][name]': 'Name',
 'columns[2][searchable]': 'true',
 'columns[2][orderable]': 'true',
 'columns[2][search][value]': '',
 'columns[2][search][regex]': 'false',
 'order[0][column]': '0',
 'order[0][dir]': 'asc',
 'order[0][name]': 'Brand',
 'start': '0',
 'length': '10',
 'search[value]': '',
 'search[regex]': 'false',
 '_': '1725412765180'}

(as a dictionary)

However, there's a variable number of columns and order values that might come through. So I'd like to convert all of this into a few key variables:

  1. start
  2. length
  3. search value
  4. search regex
  5. draw
  6. array/list of column objects
  7. array/list of order objects

But I don't know a lot of python


Solution

  • Well, that is a pure Python question and has nothing to do with the framework itself. In any case, the only way I can think of is to gather metadata and use it build a new object. Something around this:

    data = { your_current_data }
    """
    Access current data directly
    and assign possible values to the new object.
    """
    new_data = {
        "start": data.pop("start"),
        "length": data.pop("length"),
        "search_value": data.pop("search[value]"),
        "search_regex": data.pop("search[regex]"),
        "draw": data.pop("draw"),
        "columns": [],
        "orders": [],
    }
    
    """
    Find metadata to build the new object.
    1) columns: number of columns -> [0,1,2]
    2) orders: number of orders -> [0]
    3) keys_data: a matrix containing all keys 
       obtained by destructuring the original one -> 
    [ 
      [k1, k2, k3...], 
      [...], 
        .
        .
    ]
    """
    columns = []
    orders = []
    keys_data = []
    
    for key, value in data.items():
        keys = key.split("[")
        keys = [key.replace("]", "") for key in keys]
        keys.append(value)
        keys_data.append(keys)
        if keys[0] == "columns":
            if not keys[1] in columns:
                columns.append(keys[1])
        if keys[0] == "order":
            if not keys[1] in orders:
                orders.append(keys[1])
        else:
            pass
    
    """
    Use columns and orders to loop through the matrix
    and find it respective data to build a new object
    to be appended to the new_data list.
    """
    for number in columns:
        obj = {"number": number}
    
        for keys in keys_data:
            if keys[0] == "columns" and keys[1] == number:
                obj.update({f"{keys[-2]}": keys[-1]})
            else:
                pass
    
        new_data["columns"].append(obj)
    
    for number in orders:
        obj = {"number": number}
    
        for keys in keys_data:
            if keys[0] == "order" and keys[1] == number:
                obj.update({f"{keys[-2]}": keys[-1]})
            else:
                pass
    
        new_data["orders"].append(obj)
    

    If you want the new_data, columns and orders objects to contain keys called search_value and search_regex you need to adapt the code further by checking the keys list length.