0

In my Django project I have array, that looks like that:

[
   {'aa': '123', 'bb': '456','cc': '798'}, 
   {'aa': '111', 'bb': '222','cc': '333'},
   {'aa': 'a1', 'bb': 'b2','cc': 'c3'}
]

I want to write that array in the URL (e.g. website.com/?data=[{aa...},{...}]), so then I can read that data parameter, and retrieve the array.

I can't just write the array to the URL (because of the special signs), so how can I parse the array to string, then un-parse the string back to the original array (and be type 'array' - not string)?

funnydman
  • 9,083
  • 4
  • 40
  • 55
  • `import json`? https://docs.python.org/3/library/json.html By the way, "parsing" means converting from a string into structured data, not the other way round. – kaya3 Dec 22 '19 at 12:01
  • Hi @jalkjda asjdlka, if my answer is good for you, please do not hesitate to check it as answering your question :) – KrazyMax Dec 22 '19 at 14:59

3 Answers3

2

You've got a json structured array, why don't you want to send it to your view as a file? You can submit a file through your form, and get it with request.FILES.

Well, to answer your question which is more a python than a django question actually:

def transform_for_url(array_to_process):
    array_copy = str(array_to_process)
    to_replace = {
        "'": "",
        '[': '',
        ']': '',
        '{': '',
        '},': ';',
        '}': '',
        ' ': ''
    }
    for key, val in to_replace.items():
        array_copy = array_copy.replace(key, val)
    return array_copy

def get_back_from_url(url_to_process):
    new_list = []
    dicts = url_to_process.split(';')
    for single_dict in dicts:
        new_dict = {}
        for elt in single_dict.split(','):
            elt = elt.split(':')
            new_dict.update({elt[0]: elt[1]})    
        new_list.append(new_dict)
    return new_list

x = [
   {'aa': '123', 'bb': '456','cc': '798'}, 
   {'aa': '111', 'bb': '222','cc': '333'},
   {'aa': 'a1', 'bb': 'b2','cc': 'c3'}
]

y = transform_for_url(x)
print(y)
>>> aa:123,bb:456,cc:798;aa:111,bb:222,cc:333;aa:a1,bb:b2,cc:c3


print(get_back_from_url(y))
>>> [{'aa': '123', 'bb': '456', 'cc': '798'}, {'aa': '111', 'bb': '222', 'cc': '333'}, {'aa': 'a1', 'bb': 'b2', 'cc': 'c3'}]

Not the most efficient way to do it, but still does the job!

KrazyMax
  • 939
  • 6
  • 16
2

Generally speaking, the custom serializer is not what you need, it's error-prone and most likely won't work in every case. There is urllib library that can be used:

>>> from urllib.parse import urlencode, parse_qsl

>>> to_encode = [
   {'aa': '123', 'bb': '456','cc': '798'}, 
   {'aa': '111', 'bb': '222','cc': '333'},
   {'aa': 'a1', 'bb': 'b2','cc': 'c3'}
]
>>> sep = ';'
>>> encoded = sep.join([urlencode(adict, doseq=True) for adict in to_encode])
>>> print(encoded)
>>> 'aa=123&bb=456&cc=798;aa=111&bb=222&cc=333;aa=a1&bb=b2&cc=c3'

# decoding process simple as that
>>> decoded = [dict(parse_qsl(s)) for s in encoded.split(sep)]
>>> print(decoded)
>>> [{'aa': '123', 'bb': '456', 'cc': '798'}, 
     {'aa': '111', 'bb': '222', 'cc': '333'}, 
     {'aa': 'a1', 'bb': 'b2', 'cc': 'c3'}]


funnydman
  • 9,083
  • 4
  • 40
  • 55
  • The encode uses ampersands, so I guess that if I use it in URL, it will look at each item as parameter in the URL, and it will be hard to decode it (because I already have many parameters in the URL). – jalkjda asjdlka Dec 22 '19 at 16:39
  • @jalkjdaasjdlka then you could do `encoded.replace('&', ',')` and give it back before decoding. Actually the way of how to handle it framework-specific: https://stackoverflow.com/questions/6243051/how-to-pass-an-array-within-a-query-string?answertab=votes#tab-top – funnydman Dec 22 '19 at 16:49
  • When I use *encoded.replace('&', ',')*, I get something like: *[{'aa':'123, bb=456,cc=789'}, {'aa':'111, bb=222,cc=333'}]* – jalkjda asjdlka Dec 22 '19 at 17:08
  • `encoded` is a string, so for encoded: `encoded = encoded.replace('&', ',')` and for decoded: `decoded = [dict(parse_qsl(s)) for s in encoded.replace(',', '&').split(sep)]` – funnydman Dec 22 '19 at 17:15
  • 1
    Nice answer! Note: that using *sep = ';'*, gave me bugs, that were solved until I used *sep='/'* – jalkjda asjdlka Dec 23 '19 at 08:41
  • Nice! Did not know about `urlencode` and `parse_qsl` – KrazyMax Dec 27 '19 at 20:10
0

Are you looking for something like this?

>>> x
[{'aa': '123', 'bb': '456', 'cc': '798'}, {'aa': '111', 'bb': '222', 'cc': '333'}, {'aa': 'a1', 'bb': 'b2', 'cc': 'c3'}]

>>> x = str(x).replace("'", "")
>>> x
'[{aa: 123, bb: 456, cc: 798}, {aa: 111, bb: 222, cc: 333}, {aa: a1, bb: b2, cc: c3}]'

>>> url = f'website.com/data={x}'
>>> url
'website.com/data=[{aa: 123, bb: 456, cc: 798}, {aa: 111, bb: 222, cc: 333}, {aa: a1, bb: b2, cc: c3}]'

abhilb
  • 5,639
  • 2
  • 20
  • 26