【问题标题】:How do I pass a lot of parameters to views in Django?如何将大量参数传递给 Django 中的视图?
【发布时间】:2010-04-27 09:18:18
【问题描述】:

我对 Django 非常陌生,我正在尝试构建一个应用程序来以表格和图表的形式呈现我的数据。到目前为止,我的学习过程非常顺利,但现在我有点卡住了。

我的综合浏览量从数据库中检索大量数据并将其放入上下文中。然后模板生成不同的 html 表。到目前为止一切顺利。
现在我想在模板中添加不同的图表。我通过定义<img src=".../> tags. 设法做到这一点。 Matplotlib 图表是在我的图表视图中生成的,并通过以下方式返回:

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

现在我有不同的问题:

  1. 从数据库中检索数据两次。一次在页面视图中呈现表格,再次在图表视图中制作图表。将已经在页面上下文中的数据传递到图表视图的最佳方式是什么?
  2. 我需要很多图表,每个图表都有不同的数据集。我可以为每个图表制作一个图表视图,但可能有更好的方法。如何将不同的数据集名称传递给图表视图?有些图表有 20 个数据集,所以我不认为通过 url 传递这些数据集参数(如:<imgm src="chart/dataset1/dataset2/.../dataset20/chart.png />)是正确的方法。
    有什么建议吗?

【问题讨论】:

    标签: python django parameters charts


    【解决方案1】:

    您不能将数据从页面视图传递到图表视图,因为它们是单独的 HTTP 请求。您有几个选择:

    1. 传递图表 URL 中的所有数据。这听起来可能很疯狂,但这正是 Google Charts 所做的:http://code.google.com/apis/chart/docs/making_charts.html

    2. 将数据存储在会话中。页面视图将数据填充到会话中,图表视图将使用它来创建图表。

    3. 在内存缓存中缓存您的数据库查询。由于页面和图表都将引用相同的查询,因此您很可能会命中缓存。这是一个很好的解决方案,因为即使没有先渲染页面,您的图表仍然可以工作。

    4. 再次查询数据库即可。您的 DBMS 可能具有良好的缓存,性能可能不是您想象的问题。

    对于第二个问题,一个 URL 中的 20 个单词似乎没什么大不了的。当然,您也许可以为所选数据集找到一些模式,这样您就不需要每次都指定它们,但如果需要,只需制作长 URL。

    【讨论】:

    • 感谢您的回答,内德。 Nr 1:这会起作用,但我的直觉说应该有一个更“审美”的解决方案。 Nr2:这就是我要找的。这解决了我的问题
    【解决方案2】:

    使用模板标签可能是我在这里采取的路线。我遇到过类似的情况,我在同一页面上以不同的格式多次呈现日历信息。我处理它的方式是将查询的数据传递到请求上下文中,然后简单地使用该查询集作为模板标签的参数。结果是你可以得到这样的模板语法:

    查看

    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”。
    • 在该新文件夹中创建一个空白文件“init.py”
    • 将该 templatetags 文件夹的位置添加到 settings.py 中的 TEMPLATE_DIRS 设置中(如果还没有的话)

    因为我们将制作其中的几个,所以我们可以制作一个基本模板标签,我们将继承它来封装我们的基本功能......

    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')   
    

    【讨论】:

    • 谢谢 T.Stone。这可能解决了我的问题。我需要先测试一下才能确定。不管怎样,你的回答让我学到了很多关于标签的知识,这将是有用的,如果不是现在,那么在将来。
    猜你喜欢
    • 2017-12-13
    • 2012-01-17
    • 1970-01-01
    • 2020-07-11
    • 2015-09-12
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2021-08-04
    相关资源
    最近更新 更多