2009-06-30 103 views
1

我希望能够根据url参数以不同的方式显示一组数据。导出不同格式的数据集

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

例如:

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

此外,我希望能够做同样的CSV,文本,EXCEL,PDF,HTML等..

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

在HTML模式我希望能够将这些数据传递到一些模板(I”使用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> 

所以我认为有实施ented我自己的渲染器为每种类型的 - 像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) 

它是正确的做法?

回答

1

我建议有渲染器也知道的MIME类型,而不是硬编码在调用渲染器的代码是后者 - 更好地专注特定格式的知识在一个地方,所以调用代码将

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

此外,这对于注册表设计模式(if/elif是最长的树,但是您基本上决定使用哪个对象或类是完美的!)是一个很好的机会。让你无论是硬编码的字典:

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

,或者甚至更好的使渲染登记自己在起动时的字典,但可能是太超前/难安排。在这两种情况下,你的通话片断我刚才所引述的是之前有:

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

None你可以申请您的默认密码。我发现字典查找和多态性SO比维护和增强更容易比/如果/ elif树! - )

+0

好主意有默认mimetype在Renderer类,谢谢。但我不确定在render()调用中返回它。我要在我的父Renderer类中有方法get_mimetype()。例如json_renderer = JSONRenderer(); content = json_renderer。渲染(数据=数据集);返回HttpResponse(内容,mimetype = json_renderer.get_mimetype())。我更喜欢这种方式,因为将来可能会将数据呈现到文件或日志或其他任何内容中,所以我不必了解mimetype作为render()的第二个返回参数。谢谢。 – zinovii 2009-07-01 02:39:41

0

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