【发布时间】:2014-05-27 21:41:39
【问题描述】:
我已经为我的 Django 应用程序创建了一个简单的 GET only api,使用的是 sweetpie。我需要提供平面表格 CSV 数据,但我的数据库结构已标准化。 Per the documentation 我已经实现了一个自定义的Serializer 类,其to_csv() 方法如下。
def to_csv(self, data, options=None):
options = options or {}
data = self.to_simple(data, options)
raw_data = StringIO.StringIO()
writer = csv.writer(raw_data, quotechar="'", quoting=csv.QUOTE_NONNUMERIC)
if "meta" in data.keys():#if multiple objects are returned
objects = data.get("objects")
writer.writerow(objects[0].keys())
for object in objects:
test = object.values()
writer.writerow(test)
else:
writer.writerow(data.values())
CSVContent=raw_data.getvalue()
return CSVContent
这很好用,除了默认情况下将任何资源呈现为 JSON(当我在 ModelResource ForeignKey 规范中包含 full = True 时),所以我最终得到包含嵌套 JSON 数据的 CSV 数据,看起来像这样。
foodID,foodName,related_details
1,"apricot","{'type':'fruit', 'cost':'medium'}"
2,"beef","{'type':'animal', 'cost':'high'}"
3,"celery","{'type':'vegetable', 'cost':'low'}"
我想要的输出是
foodID,foodName,type,cost
1,"apricot","fruit","medium"
2,"beef","animal","high"
3,"celery","vegetable","low"
我有一个想法,我需要递归地应用我的序列化程序,然后在写入 CSV 之前合并结果,但到目前为止还没有成功。
【问题讨论】:
-
您是否正在寻找一些代码来转换您的第三个元素,例如:
line[:2] + eval(line[2]).values()在 lambda 函数中? -
这听起来很有希望,但我对 lambda 函数一无所知。它需要是通用的,因为我不想假设它总是需要转换的行中的第三个元素,因为不同的模型有不同的外键。所以需要先检测它是 JSON,然后应用转换。
-
我认为使用
DictWriter会更好。我设想乱序数据。 -
@andrew-barr 关于您的需求,我认为 lambda 函数不匹配。我在下面的答案中向您提出了一个更通用的函数,它既不依赖于 JSON 字符串的位置,也不依赖于元素的数量。
标签: python django csv serialization tastypie