尝试在 django 视图生成的网页中显示图像

我的目标是有一个简单的表单,允许用户输入一个函数来绘制图形,以及一个显示窗口,一旦用户点击提交按钮,我希望 numpy 和 matplotlib 获取表单数据并生成一个图形,然后在新网页中显示该数字。

到目前为止,我按照“创建联系表单视图”来生成表单并使数据可用。我发现这个可以让我显示图像。然而,图像就像这样占据了整个浏览器窗口。我希望该图像显示在我的网页中。我对 Django 很陌生,如果这没有意义或信息不够,我很抱歉。如果需要,我很乐意提供说明或其他信息。

这是我的应用程序的views.py:

from django.shortcuts import render

from django.http import HttpResponse

from matplotlib.backends.backend_agg import FigureCanvasAgg

from .forms import GraphingInput

from .graphing_tool import graph


import io

# Create your views here.



def grapher_tool_input(request):

    submitted = False

    if request.method == 'POST':

        form = GraphingInput(request.POST)

        if form.is_valid():

            cd = form.cleaned_data

            fig = graph(cd['left_end'], cd['right_end'], cd['top'], cd['bottom'], cd['function'])

            response = HttpResponse(content_type='image/jpg')

            canvas = FigureCanvasAgg(fig)

            canvas.print_jpg(response)

            return response

    else:

        form = GraphingInput(initial={'left_end':-10, 'right_end':10, 'bottom':-10, 'top':10})

        if 'submitted' in request.GET:

            submitted = True

        context ={

            'form': form,

            'submitted': submitted,

        }

    return render(request, 'gtdefault.html', context)

这是我的 forms.py


from django import forms



class GraphingInput(forms.Form):

    left_end = forms.FloatField(max_value=10000000, min_value=-10000000, label='Left End Point')

    right_end = forms.FloatField(max_value=10000000, min_value=-10000000, label='Right End Point')

    bottom = forms.FloatField(max_value=10000000, min_value=-10000000, label='Bottom of Window')

    top = forms.FloatField(max_value=10000000, min_value=-10000000, label='Top of Window')

    function = forms.CharField(min_length=1, label='f(x)')


子衿沉夜
浏览 113回答 2
2回答

慕娘9325324

首先,您的views.py 在 POST 的情况下返回图像。接下来的部分将告诉浏览器您返回的“页面”实际上是一张图像,并要求浏览器显示该图像。这就是为什么浏览器只显示图像。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response&nbsp;=&nbsp;HttpResponse(content_type='image/jpg') &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;canvas&nbsp;=&nbsp;FigureCanvasAgg(fig) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;canvas.print_jpg(response)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;response因此,在这两种情况下,您都应该返回呈现的模板。return render(request, 'gtdefault.html', context)我了解您想在网页中显示图像(gtdefault.html)?这意味着类似这样的事情。{%&nbsp;if&nbsp;submitted&nbsp;%} &nbsp;&nbsp;&nbsp;&nbsp;<img&nbsp;src="you&nbsp;need&nbsp;source&nbsp;here"&nbsp;/> {%&nbsp;else&nbsp;%}现在,棘手的部分是将源 URL 放入上下文中。您可以将生成的图像上传到 django meda 文件或某些外部存储(如 AWS S3)一段时间,然后使用从那里获得的 url。或者您可以按照以下方式传递页面内的图像:How to display picture from memory in Django?在第一种方法中,如果图像稍后会再次查看,则可以使用浏览器缓存。对于后一种情况,您可以忽略存储,但实现起来“更繁琐”。

拉风的咖菲猫

我将views.py中的响应更改为render(request, 'gtdefault.html', context)。为了将图像编码为base64,我必须遍历PIL的图像,然后从PIL的图像到base64。我还submitted从我的代码中删除并改为使用request.method == 'POST'. 再次感谢@Juho Rutila!我确信可能有一种不那么迂回的方法来做到这一点,但这是我可以开始工作的第一种方法。我修改后的views.py:import ioimport base64from PIL import Imagedef grapher_tool_input(request):&nbsp; &nbsp; if request.method == 'POST':&nbsp; &nbsp; &nbsp; &nbsp; form = GraphingInput(request.POST)&nbsp; &nbsp; &nbsp; &nbsp; if form.is_valid():&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cd = form.cleaned_data&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fig = graph(cd['left_end'], cd['right_end'], cd['top'], cd['bottom'], cd['function'])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf = io.BytesIO()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fig.savefig(buf, format='png')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; im = Image.open(buf)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buf2 = io.BytesIO()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; im.save(buf2, format='png')&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; im_str = base64.b64encode(buf2.getvalue()).decode()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_uri = 'data:image/png;base64,'&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data_uri += im_str&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context = dict()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context['data'] = data_uri&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return render(request, 'gtdefault.html', context)&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; form = GraphingInput(initial={'left_end':-5, 'right_end':5, 'bottom':-5, 'top':5})&nbsp; &nbsp; &nbsp; &nbsp; context ={&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'form': form,&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; return render(request, 'gtdefault.html', context)我修改后的gtdefault.html:{% extends 'base.html' %}{% block content %}{% if request.method == 'POST' %}&nbsp; &nbsp; <img src={{ data }} alt="" height="250" ,width="250">{% else %}&nbsp; &nbsp; <form action="" method="post" novalidate>&nbsp; &nbsp; &nbsp; &nbsp; <table>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {{ form.as_table }}&nbsp; &nbsp; &nbsp; &nbsp; </table>&nbsp; &nbsp; &nbsp; &nbsp; <input type="submit" value="Graph">&nbsp; &nbsp; {% csrf_token %}&nbsp; &nbsp; </form>{% endif %}{% endblock content %}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python