请记住,我是Django和Web编程的新手。
我正在尝试做一些看似简单的事情,但我无法弄清楚:
我有一个“对象查看器”模板,用于显示有关从数据库中选择的单个对象的信息,我想在页面上包括一个图形。
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以及对象的映射显示了属性信息。
现在我的问题...
我正在学习教程here,该教程使用matplotlib创建图表并将其呈现在模板中。我正在尝试使用模型中的信息创建一个简单的条形图(area2000到area2006是我的Y,而year--2000、2001,...,2006是X)。我有一个脚本,可以根据从模型中检索到的信息来创建该图(functions.chart_object_area);目前正在使用matplotlib,如本教程中所述。遵循示例1(请参见上面的example和views.py)在views.py中调用此方法并返回要渲染的对象
但是,除了waterBody和displayFields参数之外,如何返回f.getValue()?本教程将返回图表,如下所示:
return HttpResponse(f.getvalue(), content_type="image/png")
但是我要返回:
context = {'waterBody': waterBody, 'displayFields': form}
那我该如何结合两者,以便除了显示我已有的其他东西外,还可以显示该图?
我正在使用Django 1.11版
UPDATE :我已经更新了views.py中的代码,以指示如何获取要发送到图表函数的变量(请参阅#UPDATE),并在此处添加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()]。
同样,我正在按照教程here学习在Django中使用matplotlib。