Store and retrieve template code from database

548 views
Skip to first unread message

plungerman

unread,
Jul 5, 2006, 8:32:24 AM7/5/06
to Django users
greetings,

i would like to store django template code in a database and retrieve
it for display. before i go any further, does anyone foresee any
security risks with this approach? there will be control over those
users who can manipulate the data but not so much that we could monitor
what everyone would be doing at any given moment. that said, i have
not seen anything in the template code that could present a system
security danger if used maliciously.

my approach was to create a template tag to retrieve the data from the
database and then display it in a template when called. unfortunately,
when i use the templatetag in a template, the django template code is
not parsed or rendered. you see the templated code itself. for
example, {% block content %}{% endblock %}

so question two would be, how can you tell the template rendering
mechanism in django to parse the data as if it were any other template
code? below find the code for the templatetag if that will help
diagnose the problem.

thanks in advance.

yours,

steve

from django import template
from mysite.app.models import Booboo

register = template.Library()

class SomeData(template.Node):

def __init__(self,varname):
self.varname = varname

def __repr__(self):
return "<Booboo>"

def render(self, context):
context[self.varname] = Booboo.objects.get(name="somefield")
return ''

class DoGetData:
"""
{% get_data as data %}
"""
def __init__(self, tag_name):
self.tag_name = tag_name

def __call__(self, parser, token):
bits = token.contents.split()
if len(bits) != 3:
raise template.TemplateSyntaxError, "'%s' tag takes two
arguments" % bits[0]
if bits[1] != "as":
raise template.TemplateSyntaxError, "First argument to '%s'
tag must be 'as'" % bits[0]
return SomeData(bits[2])

register.tag('get_data', DoGetData('get_data'))

Malcolm Tredinnick

unread,
Jul 5, 2006, 9:00:42 AM7/5/06
to django...@googlegroups.com
On Wed, 2006-07-05 at 12:32 +0000, plungerman wrote:
> greetings,
>
> i would like to store django template code in a database and retrieve
> it for display. before i go any further, does anyone foresee any
> security risks with this approach? there will be control over those
> users who can manipulate the data but not so much that we could monitor
> what everyone would be doing at any given moment. that said, i have
> not seen anything in the template code that could present a system
> security danger if used maliciously.

It is entirely dependent on the safety of the template tags you are
using. The standard Django tags do not permit you to change data via a
template tag (see the discussion of "alters_data" in the
templates_python.txt document). But your own custom tags (or other
custom tags that are available via "load") may not be so diligently
marked.

> my approach was to create a template tag to retrieve the data from the
> database and then display it in a template when called. unfortunately,
> when i use the templatetag in a template, the django template code is
> not parsed or rendered. you see the templated code itself. for
> example, {% block content %}{% endblock %}
>
> so question two would be, how can you tell the template rendering
> mechanism in django to parse the data as if it were any other template
> code? below find the code for the templatetag if that will help
> diagnose the problem.

Unless I am missing something, you don't seem to have included the code
that actually creates the template. At some point you are going to get a
string of text out of the database and have to call

t = django.template.Template(template_string)

with the data (template_string, here). This will give you back a
template object and you can render that using the current context by
calling

t.render(context)

That last line will probably be in the render() method of whatever your
template tag is.

Also, just in passing, are you deliberately not having DoGetData inherit
from template.Node or was that a typo? I'm not sure if it's necessary
here, but I can't completely understand what your code is trying to do
(probably more my fault then yours -- I'm getting sleepy).

Does any of the above help you at all?

Regards,
Malcolm

Simon Willison

unread,
Jul 5, 2006, 9:29:14 AM7/5/06
to django...@googlegroups.com

On 5 Jul 2006, at 14:32, plungerman wrote:

> i would like to store django template code in a database and retrieve
> it for display.

The Django template system was originally designed with this exact
use-case in mind - we made sure that there was flexibility as to
where the templates were loaded from so that if we ever wanted to put
them in a database we could do exactly that.

You'll need to write a custom template loader that pulls templates
from a database table instead of the file system. How you write
custom loaders isn't yet documented ( http://www.djangoproject.com/
documentation/templates_python/#loader-types is the closest the
documentation gets) but it should be pretty simple - you'll need to
model it on the code in django/template/loaders/ . A template loader
is basically just a module with a function fitting the following
signature:

def load_template_source(template_name, template_dirs=None):
...

Hope that helps,

Simon

Adrian Holovaty

unread,
Jul 5, 2006, 10:16:00 AM7/5/06
to django...@googlegroups.com
On 7/5/06, plungerman <st...@euroleague.net> wrote:
> i would like to store django template code in a database and retrieve
> it for display.

See Hugo's implementation here:

http://code.djangoproject.com/ticket/632

It's a bit old, and I'm not sure whether he's updated it for the
newest Django -- but it could be a good starting point.

Adrian

--
Adrian Holovaty
holovaty.com | djangoproject.com

hugo

unread,
Jul 5, 2006, 12:29:25 PM7/5/06
to Django users
Hi,

Adrian Holovaty wrote:
> It's a bit old, and I'm not sure whether he's updated it for the
> newest Django -- but it could be a good starting point.

I didn't, yet. But someone on the IRC channel said he wanted to look
into that, so maybe someone else should be up with something like this.
It should mostly just involve updating the model definition, as the
rest seems to be unchanged API-wise.

bye, Georg

plungerman

unread,
Jul 5, 2006, 1:34:09 PM7/5/06
to Django users
hello malcom,

thanks for taking the time to help out.

i was simply calling the templatetag from a template itself to display
the data retrieved from the database that contains django template
code:

{% load data_template %}


{% get_data as data %}

{% if data.content %}{{ data.content }}{% endif %}

unfortunately, the problem was that the data was not being rendered, so
you see the django template script like {% block content %}{% endblock
%} . i guess that i had hoped it would be that easy. anyway, i
attempted to rewrite the templatetag as you indicated above, adding

t = django.template.Template(template_string)
t.render(context)

to the render method of the SomeData class, but having no luck. i
might have to dig into hugo's implementation.

plungerman

unread,
Jul 7, 2006, 7:46:11 AM7/7/06
to Django users
thanks to everyone for all of your assistance. in the end, i created a
custom template loader that pulls templates from a database table,
based on the dbtemplate loader that georg created for his cms system.
i already had a data model so creating the loader and adding the
correct incantations to settings.py was pretty simple.

the problem arrose when there was not a template in the database that
corresponded to a template called from a view or from urls.py. my
understanding of how TEMPLATE_LOADERS worked was that django would
check the first one, the next one listed and the next, etc, until it
found a template. if in the end no template was found, then raise an
exception. this, however, does not seem to be the case for the admin
site. i have:

TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.load_template_source',
'django.template.loaders.app_directories.load_template_source',
'myproject.myapp.loader.load_template_source',
)

django throws an exception, for example when you try to access the
flatpages section of the admin: /admin/flatpages/flatpage/ ):

DoesNotExist at /admin/flatpages/flatpage/
Templates matching query does not exist.
Request Method: GET
Request URL: http://localhost/admin/flatpages/flatpage/
Exception Type: DoesNotExist
Exception Value: Templates matching query does not exist.
Exception Location:
/home/plungerman/django_src/django/db/models/query.py in get, line 204

oddly enough, the admin home page works it seems, as does the
documentation section. can anyone shed some light on this behaviour?
i have added the django admin templates directory to the TEMPLATE_DIRS
variable in setttings.py and this does not help either. seems like i
am missing something here.

later skaters

Reply all
Reply to author
Forward
0 new messages