以不同格式导出数据集

时间:2009-06-30 23:02:17

标签: python django rendering

我希望能够根据url参数显示不同的数据集。

我的网址看起来像/ page / {limit} / {offset} / {format} /。

例如:

/page/20/0/xml/ - subset [0:20) in xml
/page/100/20/json/ - subset [20:100) in json

此外,我希望能够为csv,text,excel,pdf,html等做同样的事情......

我必须能够为不同的格式设置不同的mimetypes和内容类型。 对于 XML 应为 application / xhtml + xml ,对于csv - text / plain 等...

在HTML模式下,我希望能够将这些数据传递到某个模板中(我正在使用Django)。

我正计划让看起来像:

dataset = {
    "meta" : {"offset" : 15, "limit" : 10, "total" : 1000},
    "columns" : {"name" : "Name", "status" : "Status", "creation_date" : "Creation Date"}
    "items" : 
        [
            {"name" : "John Smith", "status" : 1, "creation_date" : "2009-06-30 10:10:09"},
            {"name" : "Joe The Plummer", "status" : 2, "creation_date" : "2009-06-30 10:10:09"}
        ]
};

并输出如下:

CSV输出:

Name, Status, Creation Date
John Smith, 1, 2009-06-30 10:10:09
Joe The Plummer, 2, 2009-06-30 10:10:09

XML输出:

<items>
    <item id="1">
        <name>John Smith</name>
        <status>1</status>
        <creation_date>2009-06-30 10:10:09</creation_date>
    </item>
    <item id="2">
        <name>Joe The Plummer</name>
        <status>2</status>
        <creation_date>2009-06-30 10:10:09</creation_date>
    </item>
</items>

所以我认为为每种类型实现了我自己的渲染器 - 比如XMLRenderer,RSSRenderer,JSONRenderer等......

if format == "xml":
    context = XMLRenderer().render(data = dataset)

    return HttpResponse(content, mimetype="application/xhtml+xml")
elif format == "json":
    context = JSONRenderer().render(data = dataset)

    return HttpResponse(content, mimetype="text/plain")
elif format == "rss":
    context = RSSRenderer(title="Some long title here", link="/page/10/10/rss/").render(data = dataset)

    return HttpResponse(content, mimetype="application/xhtml+xml")

# few more formats...

else:
    return render_to_response(SOME_TEMPLATE, dataset)

这是正确的方法吗?

2 个答案:

答案 0 :(得分:1)

我建议渲染器也知道mimetype,而不是在调用渲染器的代码中对后者进行硬编码 - 更好地将格式特定的知识集中在一个地方,因此调用代码将是

content, mimetype = renderer().render(data=dataset)
return HttpResponse(content, mimetype=mimetype)

另外,对于注册表设计模式来说这是一个很好的机会(if / elif的大多数长树,但是你基本上决定使用哪个对象或类是完美的!)。所以你要么硬编码dict:

format2renderer = dict(
  xml=XMLRenderer,
  rss=RSSRenderer,
  # ...etc...
)

或者甚至可以更好地使渲染器在启动时在dict中注册自己,但这可能太先进/难以安排。在任何一种情况下,我刚刚引用的调用片段之前的内容就是:

renderer = format2renderer.get(format)
if renderer is not None: ...

以及None时,您可以应用默认代码。我发现dict查找和多态性比if / elif树更容易维护和增强! - )

答案 1 :(得分:0)

是的,这是一种正确的方法。