2009-06-30 70 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

是的,這是一個正確的方法。