Отправка графического изображения / объекта в дополнение к результату запроса модели и другим переменным в шаблон Django - PullRequest
0 голосов
/ 11 октября 2018

Пожалуйста, имейте в виду, что я новичок в Django и веб-программировании в целом.

Я пытаюсь сделать что-то, что кажется простым, но я не могу понять:

У меня есть шаблон «Просмотр объекта», который я использую для отображения информации об одном выбранном объекте из базы данных, и я хочу включить график на странице.

models.py:

class MaxExtent(models.Model):

    id = models.IntegerField(primary_key=True)
    geoName = models.CharField('Geounit name (territories are unique geounits)', max_length=40, null=True)
    sovereignty = models.CharField('Sovereign country name', max_length=32, null=True)
    lakeName = models.CharField('GLWD Lake name', max_length=50)
    areaMax = models.FloatField('Max Extent area (km^2)')
    area2000 = models.FloatField('2000 area (km^2)')
    area2001 = models.FloatField('2001 area (km^2)')
    area2002 = models.FloatField('2002 area (km^2)')
    area2003 = models.FloatField('2003 area (km^2)')
    area2004 = models.FloatField('2004 area (km^2)')
    area2005 = models.FloatField('2005 area (km^2)')
    area2006 = models.FloatField('2006 area (km^2)')
    centerLat = models.FloatField('Latitude of centroid')
    centerLon = models.FloatField('Longitude of centroid')

    poly = models.MultiPolygonField()

    def __str__(self): # default field for string representation

        if self.lakeName:
            return "ID {}: {} ({}, {})".format(self.id, self.lakeName, self.centerLon, self.centerLat)
        else:
            return "ID {}: Not named ({}, {})".format(self.id, self.centerLon, self.centerLat)

views.py:

from django.shortcuts import get_object_or_404, render    
from django.forms import ModelForm
from .models import MaxExtent
from .functions import chart_object_areas

# Object viewer
def objectViewer(request, req_id):
    waterBody = get_object_or_404(MaxExtent, pk = req_id)

    displayFields = [str(f.name) for f in MaxExtent._meta.get_fields()]
    class MaxExtentForm(ModelForm):
        class Meta:
            model = MaxExtent
            fields = displayFields
    fields = MaxExtentForm(instance=waterBody)

    areas = [waterBody.area2000, waterBody.area2001, waterBody.area2002, waterBody.area2003, waterBody.area2004, waterBody.area2005, waterBody.area2006]
    years = [yr for yr in range(2000,2007)]
    # get the bar plot with best fit line on top
    return_chart = chart_object_areas(X = years, Y = areas, waterBody.slope, waterBody.intercept) # UPDATE

    context = {'waterBody': waterBody, 'displayFields': fields, 'chart': return_chart} # UPDATE - tried sending object to template

    return render(request, 'waterExplorer/objectViewer.html', context)

Я могу показать код шаблона, но не думаю, что это будет полезно.Просто знайте, что он успешно отображает информацию об атрибутах, используя waterBody и displayFields вместе с картой объекта.

Теперь по моему вопросу ...

Я следую учебному пособию здесь , который использует matplotlib для создания диаграммы и визуализации ее в шаблоне.Я пытаюсь создать простую гистограмму, используя информацию из модели (область 2000 - область 2006 как мой Y и год - 2000, 2001, ..., 2006 как X).У меня есть скрипт, который создает этот график на основе информации, полученной из модели (functions.chart_object_area);В настоящее время используется Matplotlib, как в учебнике.Это вызывается в views.py и возвращает объект, который должен быть визуализирован, в соответствии с примером 1 (см. пример и views.py выше)

Однако, как вернуть f.getValue () вдополнение к параметрам waterBody и displayFields?Учебник возвращает диаграмму примерно так:

    return HttpResponse(f.getvalue(), content_type="image/png")

Но я возвращаюсь:

    context = {'waterBody': waterBody, 'displayFields': form}

Так как мне объединить два, чтобы я мог отобразить график в дополнение к другим вещамУ меня уже есть?

Я использую Django версию 1.11

ОБНОВЛЕНИЕ : я обновил код в views.py, чтобы указать, как я получаю переменные. 'm отправляю в мою функцию диаграммы (см. # ОБНОВЛЕНИЕ) и добавляю сюда функцию chart_object_areas.Я также обновил файл views.py, чтобы показать, что я попытался передать выходной график в шаблон:

functions.py:

import sys
from django.http import HttpResponse
import matplotlib as mpl
mpl.use('Agg') # Required to redirect locally
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand

import cStringIO

def chart_object_areas(X, Y, slope, intercept):

    plt.ylim(0.0, np.max(Y)+(np.mean(Y)/3))
    plt.xlim(np.min(X)-1, np.max(X)+1)
    plt.ylabel('Area ($km^2$)')
    plt.xlabel('Year')
    plt.bar(X, Y)

    # plot the best fit line too
    fitY = [(slope*x + intercept) for x,d in enumerate(X)]
    plt.plot(X, fitY, color='black')


    plt.savefig('test-plot.png')
    f = cStringIO.StringIO() # redirect per tutorial
    plt.savefig(f, format="png", facecolor=(0.95,0.95,0.95))
    plt.clf()

    return f.getvalue() # per tutorial

Как видите, я сохранил рисунок и подтвердилчто функция является , создающей график.Однако, когда я пытаюсь отобразить его в шаблоне так:

{{ chart | safe }}

Ничего не появляется.Я предполагаю, что это из-за способа, которым я передаю шаблон [в учебнике, он использует content_type = "image / png" при возврате ответа, и я не знаю, как это сделать, так как я отправляю контекст вrender ()]. ​​

Опять же, я следую уроку здесь , чтобы научиться использовать matplotlib в Django.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...