Reputation: 11077
I want to take a list of data, and build a square (or near to square) block of < div> elements containing that data for rendering in an html page using django.
I've written some code that builds a square (ish) block of elements, and colours them randomly based on some input supplied as a list.
from math import sqrt, pow
import random
colour_index = {
1 : 'bg-color-primary-0',
2 : 'bg-color-primary-1',
3 : 'bg-color-primary-2',
4 : 'bg-color-primary-3',
5 : 'bg-color-primary-4',
6 : 'bg-color-secondary-0',
7 : 'bg-color-secondary-1',
8 : 'bg-color-secondary-2',
9 : 'bg-color-secondary-3',
10 : 'bg-color-tertiary-4',
11 : 'bg-color-tertiary-0',
12 : 'bg-color-tertiary-1',
13 : 'bg-color-tertiary-2',
14 : 'bg-color-tertiary-3',
15 : 'bg-color-tertiary-4'
}
width_class = {
1 : 'width100pc',
2 : 'width50pc',
3 : 'width33pc',
4 : 'width25pc',
5 : 'width20pc',
6 : 'width16pc',
7 : 'width14pc',
8 : 'width12pc',
9 : 'width11pc',
10: 'width10pc'
}
def nextSQR(anumber):
if (sqrt(anumber))==int(sqrt(anumber)):
return pow(int(sqrt(anumber)),2)
else:
return pow(int(sqrt(anumber)+1),2)
def targetshape(anumber):
return (sqrt(nextSQR(anumber)),sqrt(nextSQR(anumber)))
def divgrid(content_list):
dstring = ""
targ_shape = targetshape(len(content_list))
w = targ_shape[0]
for a in content_list:
r = random.randrange(1,10)
dstring = dstring + "<div class=\"" + colour_index.get(r) + " " + width_class.get(w) + "\">" + a + "</div>"
return dstring
In my views.py page, I get my elements from the database into a list, send the list through divgrid(), and pass the results into my context:
def home(request):
stuff_list = testContent.objects.all()
l = [a.name for a in stuff_list]
mgl = mg.divgrid(l)
context = {'grid' : mgl}
return render(request, "test.html", context)
That in turn feeds the generation of an html page through the double-courly brackets variable notation {{ grid }}
All this works fine - except, instead of seeing the results all nicely formatted within their organising div blocks, I see the html-text displayed verbatim on my page like so:
<div class="bg-color-primary-3 width33pc">Tom Kimber</div><div class="bg-color-secondary-0 width33pc">Tom</div><div class="bg-color-secondary-1 width33pc">Tom</div><div class="bg-color-primary-1 width33pc">Tom</div><div class="bg-color-secondary-3 width33pc">Tom</div><div class="bg-color-primary-1 width33pc">Lisa</div><div class="bg-color-primary-2 width33pc">Bobby Tables</div>
How do I get django to interpret my generated html code as code (i.e. rendering the divs as divs, resulting in the element-content being appropriately formatted) and not as text to be displayed as-is?
Upvotes: 0
Views: 731
Reputation: 53679
You can mark the string returned by divgrid()
as safe:
from django.utils.safestring import mark_safe
def divgrid(content_list):
...
return mark_safe(dstring)
You can then output the context variable as HTML without the need for the |safe
filter:
{{ grid }}
Upvotes: 1
Reputation: 174622
By default, and for security reasons - content passed to templates is considered unsafe and is escaped.
So <
becomes <
etc.; the end result being that your HTML is rendered instead of being parsed.
To prevent this use the safe
filter to mark variables as "safe to parse" so django will not automatically escape their contents.
In your template {{ grid|safe }}
.
Upvotes: 2