为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

子衿沉夜 2023-10-06 19:14:09
我的目标是有一个简单的表单,允许用户输入一个函数来绘制图形,以及一个显示窗口,一旦用户点击提交按钮,我希望 numpy 和 matplotlib 获取表单数据并生成一个图形,然后在新网页中显示该数字。到目前为止,我按照“创建联系表单视图”来生成表单并使数据可用。我发现这个可以让我显示图像。然而,图像就像这样占据了整个浏览器窗口。我希望该图像显示在我的网页中。我对 Django 很陌生,如果这没有意义或信息不够,我很抱歉。如果需要,我很乐意提供说明或其他信息。这是我的应用程序的views.py:from django.shortcuts import renderfrom django.http import HttpResponsefrom matplotlib.backends.backend_agg import FigureCanvasAggfrom .forms import GraphingInputfrom .graphing_tool import graphimport 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.pyfrom django import formsclass 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)')
查看完整描述

2 回答

?
慕娘9325324

TA贡献1783条经验 获得超4个赞

首先,您的views.py 在 POST 的情况下返回图像。接下来的部分将告诉浏览器您返回的“页面”实际上是一张图像,并要求浏览器显示该图像。这就是为什么浏览器只显示图像。

            response = HttpResponse(content_type='image/jpg')
            canvas = FigureCanvasAgg(fig)
            canvas.print_jpg(response) 
            return response

因此,在这两种情况下,您都应该返回呈现的模板。return render(request, 'gtdefault.html', context)

我了解您想在网页中显示图像(gtdefault.html)?这意味着类似这样的事情。

{% if submitted %}
    <img src="you need source here" />
{% else %}

现在,棘手的部分是将源 URL 放入上下文中。您可以将生成的图像上传到 django meda 文件或某些外部存储(如 AWS S3)一段时间,然后使用从那里获得的 url。

或者您可以按照以下方式传递页面内的图像:How to display picture from memory in Django?

在第一种方法中,如果图像稍后会再次查看,则可以使用浏览器缓存。对于后一种情况,您可以忽略存储,但实现起来“更繁琐”。


查看完整回答
反对 回复 2023-10-06
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

我将views.py中的响应更改为render(request, 'gtdefault.html', context)。为了将图像编码为base64,我必须遍历PIL的图像,然后从PIL的图像到base64。我还submitted从我的代码中删除并改为使用request.method == 'POST'. 再次感谢@Juho Rutila!


我确信可能有一种不那么迂回的方法来做到这一点,但这是我可以开始工作的第一种方法。


我修改后的views.py:


import io

import base64

from PIL import Image


def grapher_tool_input(request):

    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'])

            buf = io.BytesIO()

            fig.savefig(buf, format='png')

            im = Image.open(buf)

            buf2 = io.BytesIO()

            im.save(buf2, format='png')

            im_str = base64.b64encode(buf2.getvalue()).decode()

            data_uri = 'data:image/png;base64,'

            data_uri += im_str

            context = dict()

            context['data'] = data_uri

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

    else:

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

        context ={

            'form': form,

        }

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

我修改后的gtdefault.html:


{% extends 'base.html' %}


{% block content %}

{% if request.method == 'POST' %}

    <img src={{ data }} alt="" height="250" ,width="250">

{% else %}

    <form action="" method="post" novalidate>

        <table>

            {{ form.as_table }}

        </table>

        <input type="submit" value="Graph">

    {% csrf_token %}

    </form>

{% endif %}

{% endblock content %}


查看完整回答
反对 回复 2023-10-06
  • 2 回答
  • 0 关注
  • 111 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信