Code

Ticket #632: dbtemplates4.diff

File dbtemplates4.diff, 7.2 KB (added by Jannis Leidel <jl@…>, 7 years ago)

Basic tests included

Line 
1Index: django/contrib/dbtemplates/sync_templates.py
2===================================================================
3--- django/contrib/dbtemplates/sync_templates.py        (Revision 0)
4+++ django/contrib/dbtemplates/sync_templates.py        (Revision 0)
5@@ -0,0 +1,80 @@
6+"""
7+Helper function for syncing templates in TEMPLATES_DIRS with the dbtemplates
8+contrib app.
9+"""
10+
11+from django.conf import settings
12+from django.template import TemplateDoesNotExist
13+from django.contrib.dbtemplates.models import Template
14+from django.contrib.sites.models import Site
15+
16+import os
17+import sys
18+
19+try:
20+    site = Site.objects.get_current()
21+except:
22+    site = None
23+
24+def synctemplates(extension=".html", overwrite=False):
25+    """
26+    Helper function for syncing templates in TEMPLATES_DIRS with the
27+    dbtemplates contrib app.
28+    """
29+    tried = []
30+    synced = []
31+    existing = []
32+    overwritten = []
33+   
34+    if site is not None:
35+        for template_dir in settings.TEMPLATE_DIRS:
36+            if os.path.isdir(template_dir):
37+                for dirpath, subdirs, filenames in os.walk(template_dir):
38+                    for file in filenames:
39+                        if file.endswith(extension) and not file.startswith("."):
40+                            filepath = os.path.join(dirpath, file)
41+                            filename = filepath.split(template_dir)[1][1:]
42+                            try:
43+                                try:
44+                                    t = Template.objects.get(name__exact=filename)
45+                                except Template.DoesNotExist:
46+                                    filecontent = open(filepath, "r").read()
47+                                    t = Template(name=filename, content=filecontent)
48+                                    t.save()
49+                                    t.sites.add(site)
50+                                    synced.append(filename)
51+                                else:
52+                                    if overwrite:
53+                                        t.content = open(filepath, "r").read()
54+                                        t.save()
55+                                        t.sites.add(site)
56+                                        overwritten.append(t.name)
57+                                    else:
58+                                        existing.append(t.name)
59+                            except IOError:
60+                                tried.append(filepath)
61+                            except:
62+                                raise TemplateDoesNotExist
63+
64+        if len(existing) > 0:
65+            print "\nAlready existing templates:"
66+            for _existing in existing:
67+                print _existing
68+
69+        if len(overwritten) > 0:
70+            print "\nOverwritten existing templates:"
71+            for _replaced in overwritten:
72+                print _replaced
73+
74+        if len(synced) > 0:
75+            print "\nSuccessfully synced templates:"
76+            for _synced in synced:
77+                print _synced
78+
79+        if len(tried) > 0:
80+            print "\nTried to sync but failed:"
81+            for _tried in tried:
82+                print _tried
83+
84+if __name__ == "__main__":
85+    synctemplates()
86Index: django/contrib/dbtemplates/__init__.py
87===================================================================
88Index: django/contrib/dbtemplates/models.py
89===================================================================
90--- django/contrib/dbtemplates/models.py        (Revision 0)
91+++ django/contrib/dbtemplates/models.py        (Revision 0)
92@@ -0,0 +1,56 @@
93+# -*- coding: utf-8 -*-
94+from django.db import models
95+from django.template import loader, Context
96+from django.core import validators
97+from django.contrib.sites.models import Site
98+from django.utils.translation import gettext_lazy as _
99+
100+class Template(models.Model):
101+    """
102+    Defines a template model for use with the database template loader.
103+    The field ``name`` is the equivalent to the filename of a static template.
104+    """
105+    name = models.CharField(_('name'), unique=True, maxlength=100, help_text=_("Example: 'flatpages/default.html'"))
106+    content = models.TextField(_('content'))
107+    sites = models.ManyToManyField(Site)
108+    creation_date = models.DateTimeField(_('creation date'), auto_now_add=True)
109+    last_changed = models.DateTimeField(_('last changed'), auto_now=True)
110+    class Meta:
111+        db_table = 'django_template'
112+        verbose_name = _('template')
113+        verbose_name_plural = _('templates')
114+        ordering = ('name',)
115+    class Admin:
116+        fields = ((None, {'fields': ('name', 'content', 'sites')}),)
117+        list_display = ('name', 'creation_date', 'last_changed')
118+        list_filter = ('sites',)
119+        search_fields = ('name','content')
120+
121+    def __str__(self):
122+        return self.name
123+
124+__test__ = {'API_TESTS':"""
125+>>> test_site = Site.objects.get(pk=1)
126+>>> test_site
127+<Site: example.com>
128+>>> t1 = Template(name='base.html', content="<html><head></head><body>{% block content %}Welcome at {{ title }}{% endblock %}</body></html>")
129+>>> t1.save()
130+>>> t1.sites.add(test_site)
131+>>> t1
132+<Template: base.html>
133+>>> t2 = Template(name='sub.html', content='{% extends "base.html" %}{% block content %}This is {{ title }}{% endblock %}')
134+>>> t2.save()
135+>>> t2.sites.add(test_site)
136+>>> t2
137+<Template: sub.html>
138+>>> Template.objects.filter(sites=test_site)
139+[<Template: base.html>, <Template: sub.html>]
140+>>> t2.sites.all()
141+[<Site: example.com>]
142+>>> from django.contrib.dbtemplates.loader import load_template_source
143+>>> loader.template_source_loaders = [load_template_source]
144+>>> loader.get_template("base.html").render(Context({'title':'MainPage'}))
145+'<html><head></head><body>Welcome at MainPage</body></html>'
146+>>> loader.get_template("sub.html").render(Context({'title':'SubPage'}))
147+'<html><head></head><body>This is SubPage</body></html>'
148+"""}
149Index: django/contrib/dbtemplates/loader.py
150===================================================================
151--- django/contrib/dbtemplates/loader.py        (Revision 0)
152+++ django/contrib/dbtemplates/loader.py        (Revision 0)
153@@ -0,0 +1,25 @@
154+# Wrapper for loading templates from the database.
155+
156+from django.conf import settings
157+from django.template import TemplateDoesNotExist
158+from django.contrib.dbtemplates.models import Template
159+from django.contrib.sites.models import Site
160+
161+try:
162+    site = Site.objects.get_current()
163+except:
164+    site = None
165+
166+def load_template_source(template_name, template_dirs=None):
167+    """
168+    Loads templates from the database by querying the database field ``name``
169+    with a template path and ``sites`` with the current site.
170+    """
171+    if site is not None:
172+        try:
173+            t = Template.objects.get(name__exact=template_name, sites__pk=site.id)
174+            return (t.content, 'db:%s:%s' % (settings.DATABASE_ENGINE, template_name))
175+        except:
176+            pass
177+    raise TemplateDoesNotExist, template_name
178+load_template_source.is_usable = True
179Index: tests/runtests.py
180===================================================================
181--- tests/runtests.py   (Revision 5383)
182+++ tests/runtests.py   (Arbeitskopie)
183@@ -24,6 +24,7 @@
184     'django.contrib.sessions',
185     'django.contrib.comments',
186     'django.contrib.admin',
187+    'django.contrib.dbtemplates',
188 ]
189 
190 def get_test_models():