django - 如何创建一个 BytesIO img 并传递给模板

标签 django django-templates django-views bytesio

目标

我正在尝试:

  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}

最佳答案

您以错误的方式调用了 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

输出如下所示: enter image description here

关于django - 如何创建一个 BytesIO img 并传递给模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127869/

相关文章:

django - 当用户在从 UserCreation 表单继承的 UserRegister 表单上注册时,如何自动将用户添加到组

django - 从模板中的 Django 对象获取键、值对

python - 用于动态显示字典的标签串联

django - 你如何在 Jinja2 的 View (或模板)中将字符串标记为 "Safe"?

django - 如何访问 Django 模板中键的值?

django - 为什么获取复杂聚合需要别名错误?

django - 在 Django 中设置多个 MEDIA_URL 和 MEDIA_ROOT

django - 在 virtualenv 中,pip freeze > requirements.txt 提供大量垃圾!如何修剪它?

CSS 在开发人员服务器上的 Django 管理员上损坏

django - 如何在 Django 中写一些有 mustache 的东西