I am trying to write a detailed page for each row of data in the table. I would like to generate a matplotlib graph dynamically for each page using the data from each row.
I have tried the code with a normal view and it works. However, when used with the detail_view
page the image appears as a broken link. What should I include in the DetailView
class to generate the graph for each page?
graph.py
:
def plotResults(request):
p=get_object_or_404(Read_alignment,pk=id)
x =[]
y=[]
x.append(p.start)
x.append(p.stop)
y.append(p.count)
y.append(p.count)
fig=plt.figure()
ax= fig.add_subplot(311)
ax.set_xlim(right=30)
ax.step(x,y,'-',where='post', label='post')
canvas = FigureCanvas(fig)
response= HttpResponse(mimetype='image/png')
canvas.print_png(response)
return response
url.py
:
url(r'^(?P<pk>\d+)/align/plotResults.png$',plotResults),
url(r'^(?P<pk>\d+)/align/$',AlignDetailView.as_view(), name='AlignDetailView'),
views.py
:
class AlignDetailView(DetailView):
model = Read_alignment
def get_queryset(self):
queryset= Read_alignment.objects.filter(chr__icontains=3l)
return queryset
def get_context_data(self, **kwargs):
context = super(AlignDetailView,self).get_context_data(**kwargs)
context['alignment'] = self.object
return context
How should I link the graph to the template preferably without static or media tags? Is it possible to generate the graphs without saving the PNG images to the static folder?
There is a nice example here.
http://wiki.scipy.org/Cookbook/Matplotlib/Django
There are two ways to do this depending on what you want to do.
If you just want an image to be shown without any HTML, then just use a normal function view rand return a
HttpResponse
or if you really, really really want to use class based views override theget
method and return aHttpResponse
.If you want to show an HTML page with the image embedded somewhere in it. Then you can do two things
Create a separate view that will respond with just the image as you did in your example, and in your HTML page just add
<img src="path to that view url" />
.Or if you don't want a separate view for the image then you have to create an image in the DetailView, save it to byte stream, base64 encode it and return it in your context as (for example)
image
. Then in your template you create an image tag with the base64 encoded data using<img src="data:image/png;base64,{{ image }}"/>
.