[Answer]-Need a recursive CSV serializer for Django tastypie

1πŸ‘

βœ…

def to_csv(self, data, options=None):
    options = options or {}
    data = self.to_simple(data, options)

    raw_data = StringIO.StringIO()
    first = True

    if "meta" in data.keys():#if multiple objects are returned
        objects = data.get("objects")

        for value in objects:
            test = {}
            self.flatten(value, test)
            if first:
                writer = csv.DictWriter(raw_data, test.keys(), quotechar="'", quoting=csv.QUOTE_NONNUMERIC)
                writer.writeheader()
                writer.writerow(test)
                first=False
            else:
                writer.writerow(test)
    else:
        test = {}
        self.flatten(data, test)
        if first:
            writer = csv.DictWriter(raw_data, test.keys(), quotechar="'", quoting=csv.QUOTE_NONNUMERIC)
            writer.writeheader()
            writer.writerow(test)
            first=False
        else:
            writer.writerow(test)
    CSVContent=raw_data.getvalue()
    return CSVContent

def flatten(self, data, odict = {}):
    if isinstance(data, list):
        for value in data:
            self.flatten(value, odict)
    elif isinstance(data, dict):
        for (key, value) in data.items():
            if not isinstance(value, (dict, list)):
                odict[key] = value
            else:
                self.flatten(value, odict)
πŸ‘€dilbert

0πŸ‘

You can use the following function to_list on each line you have:

def to_list(line):
    idx = -1
    for i, l in enumerate(line):
        if type(l) is str and '{' in l and '}' in l:
            idx = i
            break
    if idx != -1:
        result = line[:idx] + eval(line[idx]).values() + line[idx+1:]
    else:
        result = line
    return result

if __name__ == "__main__":
    lst = [[1,"apricot","{'type':'fruit', 'cost':'medium'}"],
           ["beef","{'type':'animal', 'cost':'high'}", 3],
           ["meat", "sugar"],
           ["{'type':'car', 'cost':'nothing'}", "something"]]
    for line in lst:
        print to_list(line)

So for the following lists:

1, "apricot", "{'type':'fruit', 'cost':'medium'}"
"beef", "{'type':'animal', 'cost':'high'}", 3
"meat", "sugar"
"{'type':'car', 'cost':'nothing'}", "something"

You will get:

1, 'apricot', 'medium', 'fruit'
'beef', 'high', 'animal', 3
'meat', 'sugar'
'nothing', 'car', 'something'

As you can see it is not depending on the number of elements neither on the position of the JSON string.

πŸ‘€daouzli

Leave a comment