繁体   English   中英

如何将大量参数传递给Django中的视图?

[英]How do I pass a lot of parameters to views in Django?

我是Django的新手,我正在尝试构建一个应用程序来在表格和图表中显示我的数据。 直到现在我的学习过程非常顺利,但现在我有点卡住了。

我的网页浏览从数据库中检索大量数据并将其放入上下文中。 然后模板生成不同的html表。 到现在为止还挺好。
现在我想为模板添加不同的图表。 我设法通过定义<img src=".../> tags.来做到这一点.Matplotlib图表在我的chartview中生成一个返回的via:

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 /> )是正确的方法。
    有什么建议?

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

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

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

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

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

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

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

视图

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>

那么你怎么做那样的东西? 首先查看自定义模板标签和过滤器上的Django文档。 比Django的其他部分更难开始,但是一旦你得到它,它就很容易了。

  • 首先在应用程序的文件夹中创建一个“templatetags”文件夹。
  • 在该新文件夹中创建一个空白文件“ init .py”
  • 将该templatetags文件夹的位置添加到settings.pyTEMPLATE_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')   

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM