2010-04-27 138 views
4

我對Django很陌生,我試圖構建一個應用程序來在表格和圖表中顯示我的數據。直到現在我的學習過程非常順利,但現在我有點卡住了。如何將大量參數傳遞給Django中的視圖?

我的pageview從數據庫中檢索大量數據並將其放入上下文中。模板然後生成不同的html表格。到現在爲止還挺好。
現在我想添加不同的圖表到模板。我管理的定義<img src=".../> tags.的Matplotlib圖表中我chartview的產生通過返回做到這一點:

response=HttpResponse(content_type='image/png') 
canvas.print_png(response) 
return response 

現在我有不同的問題:

  1. 數據從數據庫中檢索的兩倍。一旦在瀏覽視圖中呈現表格,並再次在圖表視圖中製作圖表。已經在頁面上下文中將數據傳遞給chartview的最佳方式是什麼?
  2. 我需要很多圖表,每個圖表都有不同的數據集。我可以爲每個圖表製作一個圖表,但可能有更好的方法。我如何將不同的數據集名稱傳遞給chartview?有些圖表有20個數據集,所以我不認爲通過url傳遞這些數據集參數(如:<imgm src="chart/dataset1/dataset2/.../dataset20/chart.png />)是正確的。
    有什麼建議嗎?

回答

5

您無法將數據從頁面視圖傳遞到圖表視圖,因爲它們是單獨的HTTP請求。您有幾個選項:

  1. 傳遞圖表URL中的所有數據。這可能聽起來很瘋狂,但這正是Google Charts所做的:http://code.google.com/apis/chart/docs/making_charts.html

  2. 將數據存儲在會話中。頁面視圖將填充會話中的數據,並且圖表視圖將使用它來創建圖表。

  3. 在memcache中緩存你的db查詢。由於頁面和圖表都將引用相同的查詢,因此您可能會遇到緩存。這是一個很好的解決方案,因爲即使沒有首先渲染頁面,圖表仍然可以工作。

  4. 只需再次查詢數據庫。您的數據庫管理系統可能具有良好的緩存,但性能可能不是您想象的問題。

對於第二個問題,URL中的20個單詞看起來並不是什麼大不了的。當然,你也許可以找到一些選擇數據集的模式,這樣你就不需要每次都指定它們,但是如果你需要的話,只需要製作長URL。

+0

感謝您的答案,斯內德。 Nr 1:那將起作用,但我的直覺說應該有更多'estetic'解決方案。 Nr2:多數民衆贊成在我正在尋找。這解決了探頭我有 – Mark 2010-04-28 01:04:24

1

使用模板標籤可能是我在這裏要採用的路線。我遇到過類似的情況,因此我在同一頁面上以不同格式呈現多次日曆信息。我處理它的方式是將查詢的數據傳入請求上下文,然後簡單地使用該查詢集作爲模板標記的參數。其結果是,你可以用模板語法像這樣結束:

查看

def my_view(request, *args, **kwargs): 
    yearly_sales_qs = SaleRecord.objects.filter(param=value) 
    monthly_sales_qs = SalesRecord.objects.filter(param=foo) 

    return render_to_response(..., locals(), ...) 

模板

{% load data_tags %} 

<div class="year"> 
    {% render_data_table for yearly_sales_qs %} 
    {% render_bar_chart for yearly_sales_qs %} 
</div> 

<div class="month"> 
    {% render_data_table for monthly_sales_qs %} 
    {% render_bar_chart for monthly_sales_qs %} 
</div> 

那麼,如何才能讓類似的東西?首先檢查Custom template tags and filters上的Django文檔。開始比Django的其他部分要困難得多,但一旦得到它,這很容易。

  • 首先在應用程序文件夾中創建一個文件夾「templatetags」。
  • 做一個空白文件「初始化 py」爲在新的文件夾
  • 添加的位置是templatetags文件夾到TEMPLATE_DIRS設置在settings.py(如果它尚不存在)

因爲我們」會被使其中的一些,我們可以做一個基本模板標籤,我們將繼承關的實現了我們的基本功能...

data_tags.py(存儲templatetags文件夾內)

class DataForTag(tempalte.Node): 
    @classmethod 
    def handle_token(cls, parser, token, template): 
     tokens = token.contents.split() 
     if tokens[1] != 'for': 
       raise template.TemplateSyntaxError("First argument in %r must be 'for'" % tokens[0]) 

     if len(tokens) == 3: 
      return cls(queryset=parser.compile_filter(tokens[2]), template=template) 
     else: 
      raise template.TemplateSyntaxError("%r tag requires 2 arguments" % tokens[0]) 

    def __init__(self, queryset=None, template=None): 
     self.queryset = queryset 
     self.template = template 

    def render(self, context): 
     return render_to_string(self.template, {'queryset':self.queryset}) 

然後,我們可以作出這樣的處理,無論我們需要他們的個人標籤...

@register.tag 
def render_bar_chart(parser, token): 
    return DataForTag.handle_token(parser, token, 'data/charts/barchart.html') 

@register.tag 
def render_pie_chart(parser, token): 
    return DataForTag.handle_token(parser, token, 'data/charts/piechart.html')  

@register.tag 
def render_data_table(parser, token): 
    return DataForTag.handle_token(parser, token, 'data/table.html') 
+0

謝謝T.Stone。 這可能解決了我的問題。我需要首先測試它,以確保。無論如何,你的答案向我學習了很多關於標籤的知識,如果不是現在,那麼在將來會很有用。 – Mark 2010-04-28 01:07:01