Thomas Kimber
Thomas Kimber

Reputation: 11077

Get django to render python generated html passed via context parameter?

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

Answers (2)

knbk
knbk

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

Burhan Khalid
Burhan Khalid

Reputation: 174622

By default, and for security reasons - content passed to templates is considered unsafe and is escaped.

So < becomes &lt; 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

Related Questions