2010-04-27 35 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

相关问题