mirror of
https://github.com/jazzband/django-dbtemplates.git
synced 2026-03-16 22:20:28 +00:00
Merge branch 'release/1.3'
This commit is contained in:
commit
327384645c
30 changed files with 221 additions and 165 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -8,6 +8,4 @@ example/example.db
|
|||
docs/_build
|
||||
.tox/
|
||||
*.egg/
|
||||
pep8.txt
|
||||
coverage.xml
|
||||
.coverage
|
||||
.coverage
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
syntax: glob
|
||||
*.pyc
|
||||
.*.swp
|
||||
MANIFEST
|
||||
build
|
||||
dist
|
||||
django_dbtemplates.egg-info/
|
||||
example/example.db
|
||||
docs/_build
|
||||
24
.hgtags
24
.hgtags
|
|
@ -1,24 +0,0 @@
|
|||
bd537cd8beba30f1a26328e02126d3d1b14ebf8f 0.2.5
|
||||
1b426859f05b8a003411964883ed5d42ec6c1b01 0.3.0
|
||||
97da228cc698bfae05f60a68ec978030722b0777 0.3.1
|
||||
50c69325d3758d2e82541b13be2794ebbe9ee449 0.4.0
|
||||
d35a41ea96d3604a3c2654590c5c76b8865c4251 0.4.1
|
||||
a4bd56a7c2ea4c6f16a726e47bb185101934fe08 0.4.2
|
||||
447247c1ce1fbc77ac79c5855630af306f4f8c42 0.4.3
|
||||
5b2e4f7fc267daf71325991e913f98e6f96259bb 0.4.4
|
||||
ea4d636f3459ddbb51d87e921cf23f87e41d658d 0.4.5
|
||||
9a30f34bc5b07376ed6752eed94d9d58e791fbac 0.4.6
|
||||
9dc2a0e48494d6a354f5ca25db31638cede4bae4 0.4.7
|
||||
a3be97628ed8633e2fe232e6680474e7fd3e9fea 0.5.0
|
||||
bf3db2fe192d4a02bf531e61e23df342c36d6b1b 0.5.1
|
||||
67a86cf9f7c8ac8d9da855c13abbef2547033cce 0.5.2
|
||||
6967bbbee378f470e4b1df02b57112dd050d424b 0.5.3
|
||||
5965315c03c1a8c1cfb34752cca3802d68156e27 0.5.4
|
||||
4109e0db4340042cb85ea8a7d2b6ce37245738c6 0.5.5
|
||||
ade167225d06cb6888ea8bfa84e7d020590171c6 0.5.6
|
||||
dff01be9c8af328f8fcbc2fc97edcbe8d97840e2 0.5.7
|
||||
f8f7eaf275c5e8ac52174642265af55691abef7c 0.5.8
|
||||
4b36382cdfd756f45f81b0d042aaf331c3eabe30 0.6.0
|
||||
0ac352fec2c2a03ac801ff0c40f0649ef16e1f64 0.6.1
|
||||
34a0511928629872ce8cc5f94c6bed65f82ac343 0.7.0
|
||||
74c22fa8c4a64ea37f9b6b2515a4162b8b8b1a2a 0.7.1
|
||||
20
.travis.yml
Normal file
20
.travis.yml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
language: python
|
||||
python:
|
||||
# - "2.5"
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
install:
|
||||
- pip install .
|
||||
- pip install -r requirements/tests.txt Django==$DJANGO
|
||||
before_script:
|
||||
- export PIP_USE_MIRRORS=true
|
||||
- export DJANGO_SETTINGS_MODULE=dbtemplates.test_settings
|
||||
- flake8 dbtemplates --ignore=E501
|
||||
script:
|
||||
- django-admin.py test dbtemplates
|
||||
env:
|
||||
- DJANGO=1.3.1
|
||||
- DJANGO=1.4
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
4
AUTHORS
4
AUTHORS
|
|
@ -5,10 +5,14 @@ Alexander Artemenko
|
|||
Arne Brodowski
|
||||
David Paccoud
|
||||
Diego Búrigo Zacarão
|
||||
Dmitry Falk
|
||||
Jannis Leidel
|
||||
Jure Cuhalev
|
||||
Jason Mayfield
|
||||
Kevin Mooney
|
||||
Mark Stahler
|
||||
Matt Dorn
|
||||
Oliver George
|
||||
Selwin Ong
|
||||
Stephan Peijnik <spe@anexia.at>, ANEXIA Internetdienstleistungs GmbH, http://www.anexia.at/
|
||||
Zhang Kun
|
||||
|
|
|
|||
17
INSTALL
17
INSTALL
|
|
@ -1,17 +0,0 @@
|
|||
To install it, run the following command inside this directory:
|
||||
|
||||
python setup.py install
|
||||
|
||||
Or if you'd prefer you can simply place the included ``dbtemplates``
|
||||
directory somewhere on your Python path, or symlink to it from
|
||||
somewhere on your Python path; this is useful if you're working from a
|
||||
Subversion checkout. Since ``dbtemplates`` is registered in the
|
||||
Python Package Index you can also run ``easy_install django-dbtemplates``
|
||||
or ``pip install django-dbtemplates`` optionally.
|
||||
|
||||
Note that this application requires Python 2.3 or later, and a recent
|
||||
Subversion checkout of Django. You can obtain Python from
|
||||
http://www.python.org/ and Django from http://www.djangoproject.com/.
|
||||
|
||||
This install notice was bluntly stolen from James Bennett's registration
|
||||
package, http://www.bitbucket.org/ubernostrum/django-registration/
|
||||
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2007-2011, Jannis Leidel and contributors
|
||||
Copyright (c) 2007-2012, Jannis Leidel and contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
include INSTALL
|
||||
include LICENSE
|
||||
include AUTHORS
|
||||
include README.rst
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
django-dbtemplates
|
||||
==================
|
||||
|
||||
.. image:: https://secure.travis-ci.org/jezdez/django-dbtemplates.png?branch=develop
|
||||
:alt: Build Status
|
||||
:target: http://travis-ci.org/jezdez/django-dbtemplates
|
||||
|
||||
``dbtemplates`` is a Django app that consists of two parts:
|
||||
|
||||
1. It allows you to store templates in your database
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
# following PEP 386, versiontools will pick it up
|
||||
__version__ = (1, 2, 1, "final", 0)
|
||||
# following PEP 386
|
||||
__version__ = "1.3"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import posixpath
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.utils.translation import ungettext, ugettext_lazy as _
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
|
|
@ -14,7 +15,7 @@ from dbtemplates.utils.template import check_template_syntax
|
|||
if settings.DBTEMPLATES_USE_REVERSION:
|
||||
from reversion.admin import VersionAdmin as TemplateModelAdmin
|
||||
else:
|
||||
from django.contrib.admin import ModelAdmin as TemplateModelAdmin
|
||||
from django.contrib.admin import ModelAdmin as TemplateModelAdmin # noqa
|
||||
|
||||
|
||||
class CodeMirrorTextArea(forms.Textarea):
|
||||
|
|
@ -59,6 +60,14 @@ if settings.DBTEMPLATES_AUTO_POPULATE_CONTENT:
|
|||
else:
|
||||
content_help_text = ""
|
||||
|
||||
if settings.DBTEMPLATES_USE_CODEMIRROR and settings.DBTEMPLATES_USE_TINYMCE:
|
||||
raise ImproperlyConfigured("You may use either CodeMirror or TinyMCE "
|
||||
"with dbtemplates, not both. Please disable one of them.")
|
||||
|
||||
if settings.DBTEMPLATES_USE_TINYMCE:
|
||||
from tinymce.widgets import AdminTinyMCE
|
||||
TemplateContentTextArea = AdminTinyMCE
|
||||
|
||||
|
||||
class TemplateAdminForm(forms.ModelForm):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ from appconf import AppConf
|
|||
class DbTemplatesConf(AppConf):
|
||||
USE_CODEMIRROR = False
|
||||
USE_REVERSION = False
|
||||
USE_TINYMCE = False
|
||||
ADD_DEFAULT_SITE = True
|
||||
AUTO_POPULATE_CONTENT = True
|
||||
MEDIA_PREFIX = None
|
||||
|
|
@ -40,3 +41,9 @@ class DbTemplatesConf(AppConf):
|
|||
raise ImproperlyConfigured("Please add 'reversion' to your "
|
||||
"INSTALLED_APPS setting to make use of it in dbtemplates.")
|
||||
return value
|
||||
|
||||
def configure_use_tinymce(self, value):
|
||||
if value and 'tinymce' not in settings.INSTALLED_APPS:
|
||||
raise ImproperlyConfigured("Please add 'tinymce' to your "
|
||||
"INSTALLED_APPS setting to make use of it in dbtemplates.")
|
||||
return value
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from django.contrib.sites.models import Site
|
||||
from django.db import router
|
||||
from django.template import TemplateDoesNotExist
|
||||
|
||||
from dbtemplates.conf import settings
|
||||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.cache import (cache, get_cache_key,
|
||||
set_and_return, get_cache_notfound_key)
|
||||
|
|
@ -19,6 +19,12 @@ class Loader(BaseLoader):
|
|||
"""
|
||||
is_usable = True
|
||||
|
||||
def load_and_store_template(self, template_name, cache_key, site, **params):
|
||||
template = Template.objects.get(name__exact=template_name, **params)
|
||||
db = router.db_for_read(Template, instance=template)
|
||||
display_name = 'dbtemplates:%s:%s:%s' % (db, template_name, site.domain)
|
||||
return set_and_return(cache_key, template.content, display_name)
|
||||
|
||||
def load_template_source(self, template_name, template_dirs=None):
|
||||
# The logic should work like this:
|
||||
# * Try to find the template in the cache. If found, return it.
|
||||
|
|
@ -33,8 +39,6 @@ class Loader(BaseLoader):
|
|||
# in the cache indicating that queries failed, with the current
|
||||
# timestamp.
|
||||
site = Site.objects.get_current()
|
||||
display_name = 'dbtemplates:%s:%s:%s' % (settings.DATABASE_ENGINE,
|
||||
template_name, site.domain)
|
||||
cache_key = get_cache_key(template_name)
|
||||
if cache:
|
||||
try:
|
||||
|
|
@ -57,14 +61,13 @@ class Loader(BaseLoader):
|
|||
# Not marked as not-found, move on...
|
||||
|
||||
try:
|
||||
template = Template.objects.get(name__exact=template_name,
|
||||
sites__in=[site.id])
|
||||
return set_and_return(cache_key, template.content, display_name)
|
||||
return self.load_and_store_template(template_name, cache_key,
|
||||
site, sites__in=[site.id])
|
||||
except (Template.MultipleObjectsReturned, Template.DoesNotExist):
|
||||
try:
|
||||
template = Template.objects.get(name__exact=template_name)
|
||||
return set_and_return(cache_key, template.content, display_name)
|
||||
except Template.DoesNotExist:
|
||||
return self.load_and_store_template(template_name, cache_key,
|
||||
site, sites__in=[])
|
||||
except (Template.MultipleObjectsReturned, Template.DoesNotExist):
|
||||
pass
|
||||
|
||||
# Mark as not-found in cache.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from django.core.management.base import CommandError, NoArgsCommand
|
|||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.template import check_template_syntax
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Ensures templates stored in the database don't have syntax errors."
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ from dbtemplates.models import Template
|
|||
|
||||
ALWAYS_ASK, FILES_TO_DATABASE, DATABASE_TO_FILES = ('0', '1', '2')
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Syncs file system templates with the database bidirectionally."
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
|
|
@ -89,7 +90,8 @@ class Command(NoArgsCommand):
|
|||
path, t.__repr__()))
|
||||
else:
|
||||
confirm = overwrite
|
||||
if confirm in ('', FILES_TO_DATABASE, DATABASE_TO_FILES):
|
||||
if confirm in ('', FILES_TO_DATABASE,
|
||||
DATABASE_TO_FILES):
|
||||
if confirm == FILES_TO_DATABASE:
|
||||
t.content = codecs.open(path, 'r').read()
|
||||
t.save()
|
||||
|
|
@ -101,8 +103,8 @@ class Command(NoArgsCommand):
|
|||
raise CommandError(
|
||||
u"Couldn't delete %s" % path)
|
||||
elif confirm == DATABASE_TO_FILES:
|
||||
f = codecs.open(path, 'w', 'utf-8')
|
||||
try:
|
||||
f = codecs.open(path, 'w')
|
||||
f.write(t.content)
|
||||
finally:
|
||||
f.close()
|
||||
|
|
|
|||
|
|
@ -4,10 +4,11 @@ from south.db import db
|
|||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
|
||||
# Adding model 'Template'
|
||||
db.create_table('django_template', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
|
|
@ -26,16 +27,13 @@ class Migration(SchemaMigration):
|
|||
))
|
||||
db.create_unique('django_template_sites', ['template_id', 'site_id'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Template'
|
||||
db.delete_table('django_template')
|
||||
|
||||
# Removing M2M table for field sites on 'Template'
|
||||
db.delete_table('django_template_sites')
|
||||
|
||||
|
||||
models = {
|
||||
'dbtemplates.template': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'Template', 'db_table': "'django_template'"},
|
||||
|
|
|
|||
|
|
@ -1,23 +1,18 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Removing unique constraint on 'Template', fields ['name']
|
||||
db.delete_unique('django_template', ['name'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Adding unique constraint on 'Template', fields ['name']
|
||||
db.create_unique('django_template', ['name'])
|
||||
|
||||
|
||||
models = {
|
||||
'dbtemplates.template': {
|
||||
'Meta': {'ordering': "('name',)", 'object_name': 'Template', 'db_table': "'django_template'"},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from datetime import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import signals
|
||||
from django.template import TemplateDoesNotExist
|
||||
|
|
@ -13,6 +11,12 @@ from dbtemplates.conf import settings
|
|||
from dbtemplates.utils.cache import add_template_to_cache, remove_cached_template
|
||||
from dbtemplates.utils.template import get_template_source
|
||||
|
||||
try:
|
||||
from django.utils.timezone import now
|
||||
except ImportError:
|
||||
from datetime import datetime
|
||||
now = datetime.now
|
||||
|
||||
|
||||
class Template(models.Model):
|
||||
"""
|
||||
|
|
@ -25,9 +29,9 @@ class Template(models.Model):
|
|||
sites = models.ManyToManyField(Site, verbose_name=_(u'sites'),
|
||||
blank=True, null=True)
|
||||
creation_date = models.DateTimeField(_('creation date'),
|
||||
default=datetime.now)
|
||||
default=now)
|
||||
last_changed = models.DateTimeField(_('last changed'),
|
||||
default=datetime.now)
|
||||
default=now)
|
||||
|
||||
objects = models.Manager()
|
||||
on_site = CurrentSiteManager('sites')
|
||||
|
|
@ -56,7 +60,7 @@ class Template(models.Model):
|
|||
pass
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.last_changed = datetime.now()
|
||||
self.last_changed = now()
|
||||
# If content is empty look for a template with the given name and
|
||||
# populate the template instance with its content.
|
||||
if settings.DBTEMPLATES_AUTO_POPULATE_CONTENT and not self.content:
|
||||
|
|
|
|||
|
|
@ -1,26 +1,33 @@
|
|||
from __future__ import with_statement
|
||||
import codecs
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from django.conf import settings as django_settings
|
||||
from django.core.cache.backends.base import BaseCache
|
||||
from django.core.management import call_command
|
||||
from django.template import loader, Context
|
||||
from django.template import loader, Context, TemplateDoesNotExist
|
||||
from django.test import TestCase
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
from dbtemplates.conf import settings
|
||||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.cache import get_cache_backend
|
||||
from dbtemplates.utils.cache import get_cache_backend, get_cache_key
|
||||
from dbtemplates.utils.template import (get_template_source,
|
||||
check_template_syntax)
|
||||
from dbtemplates.management.commands.sync_templates import (FILES_TO_DATABASE,
|
||||
DATABASE_TO_FILES)
|
||||
|
||||
|
||||
class DbTemplatesTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.old_template_loaders = settings.TEMPLATE_LOADERS
|
||||
if 'dbtemplates.loader.Loader' not in settings.TEMPLATE_LOADERS:
|
||||
loader.template_source_loaders = None
|
||||
settings.TEMPLATE_LOADERS = (list(settings.TEMPLATE_LOADERS) +
|
||||
['dbtemplates.loader.Loader'])
|
||||
|
||||
self.site1, created1 = Site.objects.get_or_create(
|
||||
domain="example.com", name="example.com")
|
||||
self.site2, created2 = Site.objects.get_or_create(
|
||||
|
|
@ -31,6 +38,10 @@ class DbTemplatesTestCase(TestCase):
|
|||
name='sub.html', content='sub')
|
||||
self.t2.sites.add(self.site2)
|
||||
|
||||
def tearDown(self):
|
||||
loader.template_source_loaders = None
|
||||
settings.TEMPLATE_LOADERS = self.old_template_loaders
|
||||
|
||||
def test_basiscs(self):
|
||||
self.assertEqual(list(self.t1.sites.all()), [self.site1])
|
||||
self.assertTrue("base" in self.t1.content)
|
||||
|
|
@ -48,6 +59,28 @@ class DbTemplatesTestCase(TestCase):
|
|||
finally:
|
||||
settings.DBTEMPLATES_ADD_DEFAULT_SITE = old_add_default_site
|
||||
|
||||
def test_load_templates_sites(self):
|
||||
old_add_default_site = settings.DBTEMPLATES_ADD_DEFAULT_SITE
|
||||
old_site_id = django_settings.SITE_ID
|
||||
try:
|
||||
settings.DBTEMPLATES_ADD_DEFAULT_SITE = False
|
||||
t_site1 = Template.objects.create(
|
||||
name='copyright.html', content='(c) example.com')
|
||||
t_site1.sites.add(self.site1)
|
||||
t_site2 = Template.objects.create(
|
||||
name='copyright.html', content='(c) example.org')
|
||||
t_site2.sites.add(self.site2)
|
||||
|
||||
django_settings.SITE_ID = Site.objects.create(
|
||||
domain="example.net", name="example.net").id
|
||||
Site.objects.clear_cache()
|
||||
|
||||
self.assertRaises(TemplateDoesNotExist,
|
||||
loader.get_template, "copyright.html")
|
||||
finally:
|
||||
django_settings.SITE_ID = old_site_id
|
||||
settings.DBTEMPLATES_ADD_DEFAULT_SITE = old_add_default_site
|
||||
|
||||
def test_load_templates(self):
|
||||
result = loader.get_template("base.html").render(Context({}))
|
||||
self.assertEqual(result, 'base')
|
||||
|
|
@ -68,28 +101,31 @@ class DbTemplatesTestCase(TestCase):
|
|||
def test_sync_templates(self):
|
||||
old_template_dirs = settings.TEMPLATE_DIRS
|
||||
temp_template_dir = tempfile.mkdtemp('dbtemplates')
|
||||
last_path_part = temp_template_dir.split('/')[-1]
|
||||
temp_template_path = os.path.join(temp_template_dir, 'temp_test.html')
|
||||
temp_template = codecs.open(temp_template_path, 'w')
|
||||
try:
|
||||
temp_template.write('temp test')
|
||||
settings.TEMPLATE_DIRS = (temp_template_dir,)
|
||||
self.assertFalse(Template.objects.filter(name='temp_test.html').exists())
|
||||
self.assertFalse(
|
||||
Template.objects.filter(name='temp_test.html').exists())
|
||||
call_command('sync_templates',
|
||||
force=True, verbosity=0, overwrite=FILES_TO_DATABASE)
|
||||
self.assertTrue(Template.objects.filter(name='temp_test.html').exists())
|
||||
self.assertTrue(
|
||||
Template.objects.filter(name='temp_test.html').exists())
|
||||
|
||||
t = Template.objects.get(name='temp_test.html')
|
||||
t.content = 'temp test modified'
|
||||
t.save()
|
||||
call_command('sync_templates',
|
||||
force=True, verbosity=0, overwrite=DATABASE_TO_FILES)
|
||||
self.assertTrue('modified' in codecs.open(temp_template_path).read())
|
||||
self.assertTrue(
|
||||
'modified' in codecs.open(temp_template_path).read())
|
||||
|
||||
call_command('sync_templates',
|
||||
force=True, verbosity=0, delete=True, overwrite=DATABASE_TO_FILES)
|
||||
call_command('sync_templates', force=True, verbosity=0,
|
||||
delete=True, overwrite=DATABASE_TO_FILES)
|
||||
self.assertTrue(os.path.exists(temp_template_path))
|
||||
self.assertFalse(Template.objects.filter(name='temp_test.html').exists())
|
||||
self.assertFalse(
|
||||
Template.objects.filter(name='temp_test.html').exists())
|
||||
finally:
|
||||
temp_template.close()
|
||||
settings.TEMPLATE_DIRS = old_template_dirs
|
||||
|
|
@ -105,3 +141,7 @@ class DbTemplatesTestCase(TestCase):
|
|||
name='good.html', content='{% if foo %}Bar{% endif %}')
|
||||
self.assertFalse(check_template_syntax(bad_template)[0])
|
||||
self.assertTrue(check_template_syntax(good_template)[0])
|
||||
|
||||
def test_get_cache_name(self):
|
||||
self.assertEqual(get_cache_key('name with spaces'),
|
||||
'dbtemplates::name-with-spaces::1')
|
||||
|
|
@ -1,14 +1,27 @@
|
|||
DBTEMPLATES_CACHE_BACKEND = 'dummy://'
|
||||
|
||||
DATABASE_ENGINE = 'sqlite3'
|
||||
# SQLite does not support removing unique constraints (see #28)
|
||||
SOUTH_TESTS_MIGRATE = False
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
SECRET_KEY = 'something-something'
|
||||
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': ':memory:',
|
||||
}
|
||||
}
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'dbtemplates',
|
||||
'django_nose',
|
||||
]
|
||||
|
||||
TEMPLATE_LOADERS = (
|
||||
|
|
@ -16,3 +29,5 @@ TEMPLATE_LOADERS = (
|
|||
'django.template.loaders.app_directories.Loader',
|
||||
'dbtemplates.loader.Loader',
|
||||
)
|
||||
|
||||
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from django.core.cache import get_cache
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
from django.template.defaultfilters import slugify
|
||||
|
||||
from dbtemplates.conf import settings
|
||||
|
||||
|
|
@ -13,7 +14,7 @@ cache = get_cache_backend()
|
|||
|
||||
def get_cache_key(name):
|
||||
current_site = Site.objects.get_current()
|
||||
return 'dbtemplates::%s::%s' % (name, current_site.pk)
|
||||
return 'dbtemplates::%s::%s' % (slugify(name), current_site.pk)
|
||||
|
||||
|
||||
def get_cache_notfound_key(name):
|
||||
|
|
|
|||
|
|
@ -8,13 +8,11 @@ def get_loaders():
|
|||
from django.template.loader import template_source_loaders
|
||||
if template_source_loaders is None:
|
||||
try:
|
||||
from django.template.loader import (
|
||||
find_template as finder_func)
|
||||
from django.template.loader import find_template as finder
|
||||
except ImportError:
|
||||
from django.template.loader import (
|
||||
find_template_source as finder_func)
|
||||
from django.template.loader import find_template_source as finder # noqa
|
||||
try:
|
||||
source, name = finder_func('test')
|
||||
source, name = finder('test')
|
||||
except TemplateDoesNotExist:
|
||||
pass
|
||||
from django.template.loader import template_source_loaders
|
||||
|
|
|
|||
|
|
@ -1,6 +1,28 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
v1.3 (2012-05-07)
|
||||
-----------------
|
||||
|
||||
* Dropped support for Django < 1.3 **backwards incompatible**
|
||||
|
||||
* Dropped using versiontools in favor of home made solution.
|
||||
|
||||
* Added optional support for TinyMCE editor instead of the CodeMirror
|
||||
editor (just enable ``DBTEMPLATES_USE_TINYMCE``).
|
||||
|
||||
* Fixed compatibility to Django 1.4's handling of the ``DATABASES``
|
||||
setting. Should also respect database routers now.
|
||||
|
||||
* Fixed an issue of the cache key generation in combination with
|
||||
memcache's inability to stomach spaces.
|
||||
|
||||
* Moved test runner to use nose_ and a hosted CI project at Travis_:
|
||||
http://travis-ci.org/jezdez/django-dbtemplates
|
||||
|
||||
.. _nose: http://nose.rtfd.org/
|
||||
.. _Travis: http://travis-ci.org
|
||||
|
||||
v1.2.1 (2011-09-07)
|
||||
-------------------
|
||||
|
||||
|
|
|
|||
15
docs/conf.py
15
docs/conf.py
|
|
@ -16,7 +16,7 @@ import sys, os
|
|||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.append(os.path.abspath('.'))
|
||||
sys.path.append(os.path.abspath('.'))
|
||||
|
||||
# -- General configuration -----------------------------------------------------
|
||||
|
||||
|
|
@ -38,16 +38,21 @@ master_doc = 'index'
|
|||
|
||||
# General information about the project.
|
||||
project = u'django-dbtemplates'
|
||||
copyright = u'2007-2011, Jannis Leidel and contributors'
|
||||
copyright = u'2007-2012, Jannis Leidel and contributors'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '1.2'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '1.2.1'
|
||||
try:
|
||||
from dbtemplates import __version__
|
||||
# The short X.Y version.
|
||||
version = '.'.join(__version__.split('.')[:2])
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = __version__
|
||||
except ImportError:
|
||||
version = release = 'dev'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ Setup
|
|||
=====
|
||||
|
||||
1. Get the source from the `Git repository`_ or install it from the
|
||||
Python Package Index by running ``pip django-dbtemplates``.
|
||||
Python Package Index by running ``pip install django-dbtemplates``.
|
||||
2. Follow the instructions in the INSTALL file
|
||||
3. Edit the settings.py of your Django site:
|
||||
|
||||
|
|
@ -35,6 +35,11 @@ Setup
|
|||
'dbtemplates.loader.Loader',
|
||||
)
|
||||
|
||||
Order of TEMPLATE_LOADERS is important. In the former example, templates from database
|
||||
will be used as a fallback (ie. when template does not exists in other locations).
|
||||
If you want template from database to be used to override templates in other locations,
|
||||
put ``dbtemplates.loader.Loader`` at beginning of ``TEMPLATE_LOADERS`` settting.
|
||||
|
||||
4. Sync your database ``python manage.py syncdb``
|
||||
5. Restart your Django server
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ Settings
|
|||
``DBTEMPLATES_ADD_DEFAULT_SITE``
|
||||
--------------------------------
|
||||
|
||||
``dbtemplates`` adds the current site (``settings.SITE_ID``) to the database
|
||||
template when it is created by default. You can disable this feature by
|
||||
``dbtemplates`` adds the current site (``settings.SITE_ID``) to the database
|
||||
template when it is created by default. You can disable this feature by
|
||||
setting ``DBTEMPLATES_ADD_DEFAULT_SITE`` to ``False``.
|
||||
|
||||
``DBTEMPLATES_AUTO_POPULATE_CONTENT``
|
||||
|
|
@ -28,6 +28,14 @@ The dotted Python path to the cache backend class. See
|
|||
A boolean, if enabled triggers the use of the CodeMirror based editor.
|
||||
Set to ``False`` by default.
|
||||
|
||||
``DBTEMPLATES_USE_TINYMCE``
|
||||
---------------------------
|
||||
|
||||
.. versionadded:: 1.3
|
||||
|
||||
A boolean, if enabled triggers the use of the TinyMCE based editor.
|
||||
Set to ``False`` by default.
|
||||
|
||||
``DBTEMPLATES_USE_REVERSION``
|
||||
-----------------------------
|
||||
|
||||
|
|
|
|||
3
requirements/tests.txt
Normal file
3
requirements/tests.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
flake8
|
||||
django-nose
|
||||
coverage
|
||||
|
|
@ -11,3 +11,7 @@ upload-dir = docs/_build/html
|
|||
|
||||
[upload_sphinx]
|
||||
upload-dir = docs/_build/html
|
||||
|
||||
[nosetests]
|
||||
with-coverage=1
|
||||
cover-package=dbtemplates
|
||||
|
|
|
|||
24
setup.py
24
setup.py
|
|
@ -1,20 +1,33 @@
|
|||
import os
|
||||
import re
|
||||
import codecs
|
||||
from os import path
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read()
|
||||
|
||||
def read(*parts):
|
||||
return codecs.open(os.path.join(os.path.dirname(__file__), *parts)).read()
|
||||
|
||||
|
||||
def find_version(*file_paths):
|
||||
version_file = read(*file_paths)
|
||||
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
|
||||
version_file, re.M)
|
||||
if version_match:
|
||||
return version_match.group(1)
|
||||
raise RuntimeError("Unable to find version string.")
|
||||
|
||||
|
||||
setup(
|
||||
name='django-dbtemplates',
|
||||
version=':versiontools:dbtemplates:',
|
||||
version=find_version('dbtemplates', '__init__.py'),
|
||||
description='Template loader for templates stored in the database',
|
||||
long_description=read(path.join(path.dirname(__file__), 'README.rst')),
|
||||
long_description=read('README.rst'),
|
||||
author='Jannis Leidel',
|
||||
author_email='jannis@leidel.info',
|
||||
url='http://django-dbtemplates.readthedocs.org/',
|
||||
packages=find_packages(exclude=['example']),
|
||||
zip_safe=False,
|
||||
package_data = {
|
||||
package_data={
|
||||
'dbtemplates': [
|
||||
'locale/*/LC_MESSAGES/*',
|
||||
'static/dbtemplates/css/*.css',
|
||||
|
|
@ -35,5 +48,4 @@ setup(
|
|||
'Framework :: Django',
|
||||
],
|
||||
install_requires=['django-appconf >= 0.4'],
|
||||
setup_requires=['versiontools >= 1.5'],
|
||||
)
|
||||
|
|
|
|||
51
tox.ini
51
tox.ini
|
|
@ -1,51 +0,0 @@
|
|||
[tox]
|
||||
distribute = false
|
||||
envlist =
|
||||
py25-1.2.X, py26-1.2.X, py27-1.2.X,
|
||||
py25-1.3.X, py26-1.3.X, py27-1.3.X
|
||||
|
||||
[testenv]
|
||||
downloadcache = {toxworkdir}/_download/
|
||||
commands =
|
||||
{envbindir}/coverage erase
|
||||
{envbindir}/coverage run --branch --source=dbtemplates {envbindir}/django-admin.py test {posargs:dbtemplates} --settings=dbtemplates.test_settings
|
||||
{envbindir}/coverage report --omit=*test*
|
||||
{envbindir}/coverage html --omit=*test* -d {envtmpdir}
|
||||
echo "Type the following to open the coverage report: python -m webbrowser -t file://{envtmpdir}/index.html"
|
||||
|
||||
[testenv:py25-1.2.X]
|
||||
basepython = python2.5
|
||||
deps =
|
||||
coverage
|
||||
django==1.2.5
|
||||
|
||||
[testenv:py26-1.2.X]
|
||||
basepython = python2.6
|
||||
deps =
|
||||
coverage
|
||||
django==1.2.5
|
||||
|
||||
[testenv:py27-1.2.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
coverage
|
||||
django==1.2.5
|
||||
|
||||
|
||||
[testenv:py25-1.3.X]
|
||||
basepython = python2.5
|
||||
deps =
|
||||
coverage
|
||||
django==1.3
|
||||
|
||||
[testenv:py26-1.3.X]
|
||||
basepython = python2.6
|
||||
deps =
|
||||
coverage
|
||||
django==1.3
|
||||
|
||||
[testenv:py27-1.3.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
coverage
|
||||
django==1.3
|
||||
Loading…
Reference in a new issue