在Django视图中将图像作为参数发送到render()中

时间:2019-03-04 16:26:48

标签: python django django-views

我正在尝试构建一个网络应用程序,向用户显示他的体重随时间的变化。因此,我试图绘制折线图。我想在视图文件中使用matplotlib或类似的库来绘制图形。
This answer 解释了如何通过Django视图绘制图形。

我在views.py文件中的代码如下所示:(无需详细阅读,就可以正常工作)

from django.shortcuts import render, HttpResponseRedirect, HttpResponse
from .forms import DiabetesForm
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib as plt
from matplotlib.dates import DateFormatter
import datetime
import random
import io


def mplimage(request):
    f = Figure()
    ax = f.add_subplot(111)
    x = []
    y = []
    now = datetime.datetime.now()
    delta = datetime.timedelta(days=1)
    for i in range(10):
        x.append(now)
        now += delta
        y.append(random.randint(0, 1000))
    ax.plot_date(x, y, '-')
    ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
    f.autofmt_xdate()

    buf = io.BytesIO()
    canvas = FigureCanvas(f)
    canvas.print_png(buf)
    response=HttpResponse(buf.getvalue(),content_type='image/png')
    # if required clear the figure for reuse
    f.clear()
    # I recommend to add Content-Length for Django
    response['Content-Length'] = str(len(response.content))
    #
    return response

并且urls.py中的代码是:

from django.urls import path, include
from . import views
urlpatterns = [
    path('', views.mplimage, name='home'),

]

但是,此代码仅显示HTML页面中的绘制图像(在views.py文件中生成)。 我要什么:
我想将生成的图像和模板名称一起传递给render函数,以便除了图像之外,我还可以编写其他信息/内容。换句话说,我想利用HTML页面中传递的图像,该图像也可以容纳其他内容。

我也可以通过任何其他方法来完成这项工作。

编辑:我对javascript不太了解,所以除非没有其他方法,否则请不要给出与javascript相关的答案。

Edit2:这里是@Mikhail建议的更新的工作代码(第二种方法):

from django.shortcuts import render, HttpResponseRedirect, HttpResponse
from .forms import DiabetesForm
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import matplotlib as plt
from matplotlib.dates import DateFormatter
import datetime
import random
import io
import base64


def mplimage(request):
    f = Figure()
    ax = f.add_subplot(111)
    x = []
    y = []
    now = datetime.datetime.now()
    delta = datetime.timedelta(days=1)
    for i in range(10):
        x.append(now)
        now += delta
        y.append(random.randint(0, 1000))
    ax.plot_date(x, y, '-')
    ax.xaxis.set_major_formatter(DateFormatter('%Y-%m-%d'))
    f.autofmt_xdate()

    buf = io.BytesIO()
    canvas = FigureCanvas(f)
    canvas.print_png(buf)
    response=HttpResponse(buf.getvalue(),content_type='image/png')
    # if required clear the figure for reuse
    img_str = base64.b64encode(buf.getvalue())
    data_url = 'data:image/jpg;base64,' + base64.b64encode(buf.getvalue()).decode()
    f.clear()
    # I recommend to add Content-Length for Django
    #response['Content-Length'] = str(len(response.content))
    #
    #return response
    return render(request, "display.html", {'image': data_url })

这是display.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Display</title>
</head>
<body>
    <img src="{{ image }}" alt=""/>
    <h1>Write whatever you want</h1>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

您想要的是将图像嵌入HTML页面。

我在这里看到两个选项:

  1. 分别加载图像:
    使用此选项,您将创建两个Django视图。一种将呈现图像,另一种将使用带有引用图像的<img>标签的HTML内容。因此,用户将打开HTML网址并在其中看到图片。

  2. 返回嵌入了data: URL图像的HTML页面:
    您需要将图像从字节串(代码中的buf.getvalue())转换为base64字符串,并构造形式为data:image/png;base64,YOUR_IMAGE_BASE64_CONTENT的URL,然后使用{{1 }}设置为构造的URL。