Templatetags のテンプレをモデルにいれると、スケジューリングできたりいろいろ便利かなと思ってやってみました。
myproject/app/models.py
from django.db import models
from django.contrib.sites.models import Site
from datetime import datetime
class Block(models.Model):
name = models.CharField(blank=False, maxlength=200)
slug = models.SlugField(blank=False, maxlength=20, unique=True)
url = models.URLField(blank=False, verify_exists=False,\
default="http://%s/#slug" % Site.objects.get_current(), )
default_template = models.TextField(blank=False, default='<div id="slug"></div>')
add = models.DateTimeField(auto_now_add=True, editable=False)
mod = models.DateTimeField(auto_now=True, editable=False)
def __str__(self):
return "%s" % self.name
def get_absolute_url(self):
return self.url
class Source(models.Model):
block = models.ForeignKey(Block)
open_date = models.DateTimeField(blank=False, default=datetime.now())
enabled = models.BooleanField(default=True)
template = models.TextField(blank=False)
add = models.DateTimeField(auto_now_add=True, editable=False)
mod = models.DateTimeField(auto_now=True, editable=False)
def __str__(self):
return "%s" % self.block.name
def get_absolute_url(self):
return self.block.url
class Meta:
get_latest_by = "open_date"
myproject/app/tamplatetags/app_extras.py
from django.template import Node, Library, Context, Template, TemplateSyntaxError
from myproject.app.models import Block, Source
from datetime import datetime
register = Library()
class TemplateRender(Node):
def __init__(self, name):
try:
self.template = Source.objects.filter(
block__slug=name, enabled=True, open_date__lte=datetime.now()
).latest().template
except Source.DoesNotExist:
try:
self.template = Block.objects.get(slug=name).default_template
except Block.DoesNotExist:
self.template = None
def render(self, context):
if self.template:
self.t = Template(self.template)
return self.t.render(context)
else:
return ""
def template_render(parser, token):
tag_name, strings = token.split_contents()
bits = strings.split()
if not len(bits) == 1:
raise TemplateSyntaxError
return TemplateRender(bits[0])
register.tag(template_render)
myproject/app/tests.py
>>> from django.template import Context, Template
>>> t = Template("{% load app_extras %}{% template_render slug %}")
>>> t.render(Context({}))
'<div id="slug"></div>'
Context も使えます。 ちなみに Template name は '<Unknown Template>' になります。
