【问题标题】:How to create an BytesIO img and pass to template如何创建 BytesIO img 并传递给模板
【发布时间】:2019-04-07 05:55:40
【问题描述】:

目标

我正在尝试:

  1. 创建直方图,
  2. 暂时存储它,
  3. 将图像传递给模板。

我在执行上述第 3 步时遇到问题。我怀疑我在将context 数据传递给模板时犯了一个简单而根本的错误。

错误

HTML 正在呈现带有损坏的图像标签。

代码

Views.py

class SearchResultsView(DetailView):

   ...

   def get(self, request, *args, **kwargs):
        self.get_histogram(request)
        return super(SearchResultsView, self).get(request, *args, **kwargs)


    def get_context_data(self, **kwargs):
        context = super(SearchResultsView, self).get_context_data(**kwargs)
        return context


    def get_histogram(self, request):
        """ Function to create and save histogram of Hashtag.locations """
        # create the histogram
        plt.show()
        img_in_memory = BytesIO()
        plt.savefig(img_in_memory, format="png")
        image = base64.b64encode(img_in_memory.getvalue())
        context = {'image':image}
        return context

Results.html

<img src="data:image/png;base64,{{image}}" alt="Location Histogram" />

解决方案

除了下面@ruddra 概述的getget_context_data 的问题之外,另一个问题是我必须将base64 字符串解码为Unicode 字符串。如需更多信息,请参阅here

为此,我添加了:image = image.decode('utf8')

所以,views.py 看起来像这样:

def get_histogram(self, request):
    # draw histogram
    plt.show()
    img_in_memory = BytesIO()
    plt.savefig(img_in_memory, format="png") # save the image in memory using BytesIO
    img_in_memory.seek(0) # rewind to beginning of file
    image = base64.b64encode(img_in_memory.getvalue()) # load the bytes in the context as base64
    image = image.decode('utf8')
    return {'image':image}

【问题讨论】:

    标签: django django-templates django-views bytesio


    【解决方案1】:

    您以错误的方式调用get_histogram。你可以这样做:

    class SearchResultsView(DetailsView):
        ...
    
        def get_context_data(self, **kwargs):
             context = super(SearchResultsView, self).get_context_data(**kwargs)
             context.update(self.get_histogram(self.request))
             return context
    

    您无需在get 中调用get_histogram 方法,或覆盖get 方法。

    更新

    我试过这样:

     class SearchResultsView(DetailsView):
         ...
    
         def get_histogram(self):
             x = 2
             y = 3
             z = 2
             t= 3    
             plt.plot(x, y)
             plt.plot(z, t)
             plt.show()
             img_in_memory = io.BytesIO()  # for Python 3
             plt.savefig(img_in_memory, format="png")
             image = base64.b64encode(img_in_memory.getvalue())
             return {'image':image}
    
         def get_context_data(self, *args, **kwargs):
             context = super(SearchResultsView, self).get_context_data(*args, **kwargs)
             context.update(self.get_histogram())
             return context
    

    输出如下所示:

    【讨论】:

    • 谢谢@ruddra,我已经按照建议修改了get。但是,results.html 仍然使用损坏的图像标签进行渲染,我希望直方图会出现!
    • 抱歉,我可能无法为您的 repo 提供帮助,但我可能会帮助您调试问题。在模板中,只需将{{image}} 放在某处,不带标签并检查是否有任何内容来自上下文。如果您什么也得不到,在这种情况下,图像生成可能会出现问题。
    • 这意味着,您可以将数据从视图发送到模板,但问题出在其他地方,可能在绘图中。
    • 谢谢@ruddra,我不相信它在绘图中,因为我使用了你的绘图示例,但它仍然不起作用。相反,我现在怀疑这个问题可能是由于“styles.css”没有正确加载造成的。无论如何,我确定它超出了原始查询的范围,因此已将您的答案标记为已接受。
    • 只是为了让你知道,我在查询@ruddra 中包含了解决方案,再次感谢:)
    猜你喜欢
    • 2016-06-03
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    • 2011-09-14
    • 2021-07-26
    • 2017-09-20
    • 1970-01-01
    相关资源
    最近更新 更多