Problem in short:
How do I display a dynamic image on a template, when the function to create the image requires arguments, like an arbitrary long list of coordinates..?
for example <img src="{% url getComplexImg coords %}"/>, where coords is a list of arbitrary length consisting of either integers or tuples of integers, and getComplexImg is a view which returns an image as HttpResponse where mimetype is image/png, and where the image is generated with the list of coordinates.
EDIT: I have added a solution (inspired by the first answer) to the bottom.
The problem, long version
Following is a simplification of what I’m trying to do
urls.py:
urlpatterns = patterns('',
url(r'^getSimpleImg$', views.getSimpleImg, name='getSimpleImg'),
url(r'^getComplexImg$', views.getComplexImg, name='getComplexImg'),
url(r'^showAllImgs$', views.showAllImgs, name='showAllImgs')
)
views.py:
...
from django.template import Context, loader
...
def getSimpleImg(request):
return HttpResponse(getImg.simple(), mimetype="image/png")
def getComplexImg(request, coords_1, coords_2):
return HttpResponse(getImg.complex(coords_1,coords_2), mimetype="image/png")
def showAllImgs(request):
coords_1, coords_2 = data_module.get_all_coordinates()
context = Context({
'coords_1':coords_1,
'coords_2':coords_2})
template = loader.get_template('showall.html')
return HttpResponse(template.render(context))
‘data_module.get_all_coordinates()’ is just a method which returns two lists of arbitrary length (the lists could contain either integers or tuples of integers).
showall.html:
<html>
...
<img src="{% url getSimpleImg %}"/>
<img src="{% url getComplexImg coords_1 coords_2 %}"/>
...
</html>
It is very easy to make Django display the image returned from ‘getSimpleImg’, because it doesn’t need any list arguments. But I’m struggling to make Django display the complex image, because I down’t know how to pass on an arbitrary list as argument from the template.
The code above obviously doesn’t work because Django can’t lookup ‘{% url getComplexImg coords_1 coords_2 %}’ in the urls.py.
How should this kind of problem be solved?
Should I for example somehow send the images with the context? like:
views.py:
...
def showAllImgs(request):
coords_1, coords_2 = data_module.get_all_coordinates()
context = Context({
'img_1':getImg.simple(),
'img_2':getImg.complex(coords_1,coords_2)})
template = loader.get_template('showall.html')
return HttpResponse(template.render(context))
showall.html:
<html>
...
<img src="{{ img_1 }}"/>
<img src="{{ img_2 }}"/>
...
</html>
(above doesn’t work, it’s just to illustrate what I mean)
OR should I somehow import all the stuff I need into the template and then create and display images from there..? like:
showall.html:
{% import data_module %}
{% import getImg %}
<html>
...
<img src="{% getImg.simple() %}"/>
<img src="{% getImg.complex(data_module.get_all_coordinates()) %}"/>
...
</html>
Solution, inspired by first answer
I am solving it for now by passing on the context as:
Context({'coords_1':"_".join([str(v) for v in coords_1])})
and catching the url in urls.py with :
url(r'^getComplexImg/(?P<coords_1>[0-9_\-]+)/$', views.getComplexImg, name='getComplexImg')
And in my getComplexImg view, I convert the stringed lists back to real lists with:
coords_1 = [int(v) for v in coords_1.split('_')]
It works and I am satisfied for now, but I have a bad feeling that this might not be the most optimal solution
It looks as though your
urls.pyis malformed.You can pass variables via your urls. By using the correct syntax (the variables as regexs) you can refer to these variables when calling the
url()or{% url %}, as you are trying to do.This simple example comes from here:
http://www.djangobook.com/en/2.0/chapter08.html#using-default-view-arguments
urls.py
views.py
The bit that matters here is:
(?P<num>\d+)You can then pass whatever is in the
<here>to your view function, eg:def my_view(request, here): ...In your case you would replace the following:
To something like this:
You many not want to use named variables in your urls, but should that be the case you cannot use
{% url %}either and would need to find another solution.