mirror of
https://github.com/jazzband/django-dbtemplates.git
synced 2026-03-16 22:20:28 +00:00
Merge pull request #81 from jazzband/python3
Port to Python 3 and get rid of legacy code
This commit is contained in:
commit
62ba054698
29 changed files with 242 additions and 491 deletions
6
.coveragerc
Normal file
6
.coveragerc
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
[run]
|
||||
source = dbtemplates
|
||||
branch = 1
|
||||
|
||||
[report]
|
||||
omit = *tests*,*migrations*
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,7 +4,6 @@ MANIFEST
|
|||
build
|
||||
dist
|
||||
*.egg-info
|
||||
example/example.db
|
||||
docs/_build
|
||||
.tox/
|
||||
*.egg/
|
||||
|
|
|
|||
56
.travis.yml
56
.travis.yml
|
|
@ -1,34 +1,32 @@
|
|||
language: python
|
||||
python: 3.5
|
||||
sudo: false
|
||||
cache: pip
|
||||
language: python
|
||||
python:
|
||||
- 2.6
|
||||
- 2.7
|
||||
install:
|
||||
- pip install -e .
|
||||
- pip install -r requirements/tests.txt Django==$DJANGO
|
||||
before_script:
|
||||
- flake8 dbtemplates --ignore=E501 --exclude=migrations
|
||||
script:
|
||||
- coverage run --branch --source=dbtemplates `which django-admin.py` test dbtemplates
|
||||
- coverage report --omit="dbtemplates/test*,dbtemplates/migrations*"
|
||||
env:
|
||||
global:
|
||||
- DJANGO_SETTINGS_MODULE=dbtemplates.test_settings
|
||||
matrix:
|
||||
- DJANGO="1.4.5 importlib"
|
||||
- DJANGO="1.5.1 importlib"
|
||||
- DJANGO=1.7.8
|
||||
- DJANGO=1.8.11
|
||||
- DJANGO=1.9.4
|
||||
matrix:
|
||||
exclude:
|
||||
- python: 2.6
|
||||
env: DJANGO=1.7.8
|
||||
- python: 2.6
|
||||
env: DJANGO=1.8.11
|
||||
- python: 2.6
|
||||
env: DJANGO=1.9.4
|
||||
- TOXENV=flake8-py27
|
||||
- TOXENV=flake8-py35
|
||||
- TOXENV=readme-py27
|
||||
- TOXENV=py27-dj18
|
||||
- TOXENV=py27-dj19
|
||||
- TOXENV=py27-dj110
|
||||
- TOXENV=py27-djmaster
|
||||
- TOXENV=py34-dj18
|
||||
- TOXENV=py34-dj19
|
||||
- TOXENV=py34-dj110
|
||||
- TOXENV=py34-djmaster
|
||||
- TOXENV=py35-dj18
|
||||
- TOXENV=py35-dj19
|
||||
- TOXENV=py35-dj110
|
||||
- TOXENV=py35-djmaster
|
||||
- TOXENV=pypy-dj18
|
||||
- TOXENV=pypy-dj19
|
||||
- TOXENV=pypy-dj110
|
||||
- TOXENV=pypy-djmaster
|
||||
install:
|
||||
- pip install tox codecov
|
||||
script: tox -v
|
||||
after_success:
|
||||
- codecov
|
||||
deploy:
|
||||
provider: pypi
|
||||
user: jazzband
|
||||
|
|
@ -39,4 +37,4 @@ deploy:
|
|||
tags: true
|
||||
repo: jazzband/django-dbtemplates
|
||||
python: "2.7"
|
||||
condition: "$DJANGO = 1.8.11"
|
||||
condition: "$TOXENV = py27-dj110"
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2007-2012, Jannis Leidel and contributors
|
||||
Copyright (c) 2007-2016, Jannis Leidel and contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
|||
18
README.rst
18
README.rst
|
|
@ -1,14 +1,18 @@
|
|||
django-dbtemplates
|
||||
==================
|
||||
|
||||
.. image:: https://secure.travis-ci.org/jazzband/django-dbtemplates.png
|
||||
:alt: Build Status
|
||||
:target: http://travis-ci.org/jazzband/django-dbtemplates
|
||||
|
||||
.. image:: https://jazzband.co/static/img/badge.svg
|
||||
:alt: Jazzband
|
||||
:target: https://jazzband.co/
|
||||
|
||||
.. image:: https://travis-ci.org/jazzband/django-dbtemplates.svg?branch=master
|
||||
:alt: Build Status
|
||||
:target: http://travis-ci.org/jazzband/django-dbtemplates
|
||||
|
||||
.. image:: https://codecov.io/github/jazzband/django-dbtemplates/coverage.svg?branch=master
|
||||
:alt: Codecov
|
||||
:target: https://codecov.io/github/jazzband/django-dbtemplates?branch=master
|
||||
|
||||
``dbtemplates`` is a Django app that consists of two parts:
|
||||
|
||||
1. It allows you to store templates in your database
|
||||
|
|
@ -24,10 +28,4 @@ The source code and issue tracker can be found on Github:
|
|||
|
||||
https://github.com/jazzband/django-dbtemplates
|
||||
|
||||
Compatibility Roadmap
|
||||
---------------------
|
||||
|
||||
- 1.3.2 ``dbtemplates`` dropped support for Django < 1.4
|
||||
- 1.4 will be supported only Django >= 1.7, please freeze your requirements on specific version of ``dbtemplates`` !
|
||||
|
||||
.. _template loader: http://docs.djangoproject.com/en/dev/ref/templates/api/#loader-types
|
||||
|
|
|
|||
|
|
@ -1,2 +1 @@
|
|||
# following PEP 386
|
||||
__version__ = "1.3.2"
|
||||
__version__ = "2.0"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
import django
|
||||
from django.contrib.sites.models import Site
|
||||
from django.db import router
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.template.loaders.base import Loader as BaseLoader
|
||||
|
||||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.cache import (cache, get_cache_key,
|
||||
set_and_return, get_cache_notfound_key)
|
||||
|
||||
if django.get_version() >= '1.8':
|
||||
from django.template.loaders.base import Loader as tLoaderCls
|
||||
else:
|
||||
from django.template.loader import BaseLoader as tLoaderCls # noqa
|
||||
|
||||
|
||||
class Loader(tLoaderCls):
|
||||
class Loader(BaseLoader):
|
||||
"""
|
||||
A custom template loader to load templates from the database.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
from django.core.management.base import CommandError, NoArgsCommand
|
||||
from django.core.management.base import CommandError, BaseCommand
|
||||
|
||||
from dbtemplates.models import Template
|
||||
from dbtemplates.utils.template import check_template_syntax
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
class Command(BaseCommand):
|
||||
help = "Ensures templates stored in the database don't have syntax errors."
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
def handle(self, **options):
|
||||
errors = []
|
||||
for template in Template.objects.all():
|
||||
valid, error = check_template_syntax(template)
|
||||
|
|
@ -16,6 +16,4 @@ class Command(NoArgsCommand):
|
|||
if errors:
|
||||
raise CommandError(
|
||||
'Some templates contained errors\n%s' % '\n'.join(errors))
|
||||
# NOTE: printing instead of using self.stdout.write to maintain
|
||||
# Django 1.2 compatibility
|
||||
print('OK')
|
||||
self.stdout.write('OK')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import sys
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import CommandError, NoArgsCommand
|
||||
from django.core.management.base import CommandError, BaseCommand
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
from dbtemplates.models import Template
|
||||
|
|
@ -26,14 +24,15 @@ TEMPLATES = {
|
|||
}
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
class Command(BaseCommand):
|
||||
help = "Creates the default error templates as database template objects."
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option("-f", "--force", action="store_true", dest="force",
|
||||
default=False,
|
||||
help="overwrite existing database templates"),)
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"-f", "--force", action="store_true", dest="force",
|
||||
default=False, help="overwrite existing database templates")
|
||||
|
||||
def handle(self, **options):
|
||||
force = options.get('force')
|
||||
try:
|
||||
site = Site.objects.get_current()
|
||||
|
|
|
|||
|
|
@ -1,56 +1,54 @@
|
|||
import io
|
||||
import os
|
||||
import codecs
|
||||
from optparse import make_option
|
||||
from django import VERSION
|
||||
from django.contrib.sites.models import Site
|
||||
from django.core.management.base import CommandError, NoArgsCommand
|
||||
from django.core.management.base import CommandError, BaseCommand
|
||||
from django.template.utils import get_app_template_dirs
|
||||
from django.template.loader import _engine_list
|
||||
try:
|
||||
from django.utils.six import input as raw_input
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
from dbtemplates.conf import settings
|
||||
from dbtemplates.models import Template
|
||||
|
||||
ALWAYS_ASK, FILES_TO_DATABASE, DATABASE_TO_FILES = ('0', '1', '2')
|
||||
|
||||
DIRS = []
|
||||
|
||||
if VERSION[:2] < (1, 8):
|
||||
from django.template.loaders.app_directories import app_template_dirs
|
||||
DIRS = settings.TEMPLATE_DIRS
|
||||
else:
|
||||
from django.template.utils import get_app_template_dirs
|
||||
from django.template.loader import _engine_list
|
||||
for engine in _engine_list():
|
||||
for engine in _engine_list():
|
||||
DIRS.extend(engine.dirs)
|
||||
app_template_dirs = get_app_template_dirs('templates')
|
||||
app_template_dirs = get_app_template_dirs('templates')
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
class Command(BaseCommand):
|
||||
help = "Syncs file system templates with the database bidirectionally."
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option("-e", "--ext",
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"-e", "--ext",
|
||||
dest="ext", action="store", default="html",
|
||||
help="extension of the files you want to "
|
||||
"sync with the database [default: %default]"),
|
||||
make_option("-f", "--force",
|
||||
"sync with the database [default: %default]")
|
||||
parser.add_argument(
|
||||
"-f", "--force",
|
||||
action="store_true", dest="force", default=False,
|
||||
help="overwrite existing database templates"),
|
||||
make_option("-o", "--overwrite",
|
||||
help="overwrite existing database templates")
|
||||
parser.add_argument(
|
||||
"-o", "--overwrite",
|
||||
action="store", dest="overwrite", default='0',
|
||||
help="'0' - ask always, '1' - overwrite database "
|
||||
"templates from template files, '2' - overwrite "
|
||||
"template files from database templates"),
|
||||
make_option("-a", "--app-first",
|
||||
"template files from database templates")
|
||||
parser.add_argument(
|
||||
"-a", "--app-first",
|
||||
action="store_true", dest="app_first", default=False,
|
||||
help="look for templates in applications "
|
||||
"directories before project templates"),
|
||||
make_option("-d", "--delete",
|
||||
"directories before project templates")
|
||||
parser.add_argument(
|
||||
"-d", "--delete",
|
||||
action="store_true", dest="delete", default=False,
|
||||
help="Delete templates after syncing"))
|
||||
help="Delete templates after syncing")
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
def handle(self, **options):
|
||||
extension = options.get('ext')
|
||||
force = options.get('force')
|
||||
overwrite = options.get('overwrite')
|
||||
|
|
@ -66,10 +64,6 @@ class Command(NoArgsCommand):
|
|||
raise CommandError("Please make sure to have the sites contrib "
|
||||
"app installed and setup with a site object")
|
||||
|
||||
if not type(settings.TEMPLATE_DIRS) in (tuple, list):
|
||||
raise CommandError("Please make sure settings.TEMPLATE_DIRS is a "
|
||||
"list or tuple.")
|
||||
|
||||
if app_first:
|
||||
tpl_dirs = app_template_dirs + DIRS
|
||||
else:
|
||||
|
|
@ -93,8 +87,8 @@ class Command(NoArgsCommand):
|
|||
"database.\nCreate it with '%s'?"
|
||||
" (y/[n]): """ % (name, path))
|
||||
if force or confirm.lower().startswith('y'):
|
||||
t = Template(name=name,
|
||||
content=codecs.open(path, "r").read())
|
||||
with io.open(path, encoding='utf-8') as f:
|
||||
t = Template(name=name, content=f.read())
|
||||
t.save()
|
||||
t.sites.add(site)
|
||||
else:
|
||||
|
|
@ -111,7 +105,8 @@ class Command(NoArgsCommand):
|
|||
if confirm in ('', FILES_TO_DATABASE,
|
||||
DATABASE_TO_FILES):
|
||||
if confirm == FILES_TO_DATABASE:
|
||||
t.content = codecs.open(path, 'r').read()
|
||||
with io.open(path, encoding='utf-8') as f:
|
||||
t.content = f.read()
|
||||
t.save()
|
||||
t.sites.add(site)
|
||||
if delete:
|
||||
|
|
@ -121,11 +116,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:
|
||||
with io.open(path, 'w', encoding='utf-8') as f:
|
||||
f.write(t.content)
|
||||
finally:
|
||||
f.close()
|
||||
if delete:
|
||||
t.delete()
|
||||
break
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ class Migration(migrations.Migration):
|
|||
('sites', '0001_initial'),
|
||||
]
|
||||
|
||||
if django.get_version() >= '1.8':
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Template',
|
||||
|
|
@ -36,36 +35,10 @@ class Migration(migrations.Migration):
|
|||
'verbose_name_plural': 'templates',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
managers = [
|
||||
managers=[
|
||||
('objects', django.db.models.manager.Manager()),
|
||||
('on_site', django.contrib.sites.managers.CurrentSiteManager(
|
||||
b'sites')),
|
||||
],
|
||||
),
|
||||
]
|
||||
else:
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Template',
|
||||
fields=[
|
||||
('id', models.AutoField(
|
||||
verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(
|
||||
help_text="Example: 'flatpages/default.html'", max_length=100, verbose_name='name')),
|
||||
('content', models.TextField(verbose_name='content', blank=True)),
|
||||
('creation_date', models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name='creation date')),
|
||||
('last_changed', models.DateTimeField(
|
||||
default=django.utils.timezone.now, verbose_name='last changed')),
|
||||
('sites', models.ManyToManyField(
|
||||
to='sites.Site', verbose_name='sites', blank=True)),
|
||||
],
|
||||
options={
|
||||
'ordering': ('name',),
|
||||
'db_table': 'django_template',
|
||||
'verbose_name': 'template',
|
||||
'verbose_name_plural': 'templates',
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,12 +9,7 @@ from django.db import models
|
|||
from django.db.models import signals
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
try:
|
||||
from django.utils.timezone import now
|
||||
except ImportError:
|
||||
from datetime import datetime
|
||||
now = datetime.now
|
||||
from django.utils.timezone import now
|
||||
|
||||
|
||||
class Template(models.Model):
|
||||
|
|
|
|||
|
|
@ -1,55 +0,0 @@
|
|||
# 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):
|
||||
|
||||
# Adding model 'Template'
|
||||
db.create_table('django_template', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)),
|
||||
('content', self.gf('django.db.models.fields.TextField')(blank=True)),
|
||||
('creation_date', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
|
||||
('last_changed', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
|
||||
))
|
||||
db.send_create_signal('dbtemplates', ['Template'])
|
||||
|
||||
# Adding M2M table for field sites on 'Template'
|
||||
db.create_table('django_template_sites', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('template', models.ForeignKey(orm['dbtemplates.template'], null=False)),
|
||||
('site', models.ForeignKey(orm['sites.site'], null=False))
|
||||
))
|
||||
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'"},
|
||||
'content': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_changed': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}),
|
||||
'sites': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['sites.Site']", 'symmetrical': 'False'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['dbtemplates']
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
# encoding: utf-8
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
|
||||
|
||||
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'"},
|
||||
'content': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'creation_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_changed': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'sites': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['sites.Site']", 'symmetrical': 'False'})
|
||||
},
|
||||
'sites.site': {
|
||||
'Meta': {'ordering': "('domain',)", 'object_name': 'Site', 'db_table': "'django_site'"},
|
||||
'domain': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['dbtemplates']
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import codecs
|
||||
import io
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
|
|
@ -6,7 +6,7 @@ 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, TemplateDoesNotExist
|
||||
from django.template import loader, TemplateDoesNotExist
|
||||
from django.test import TestCase
|
||||
|
||||
from django.contrib.sites.models import Site
|
||||
|
|
@ -82,9 +82,9 @@ class DbTemplatesTestCase(TestCase):
|
|||
settings.DBTEMPLATES_ADD_DEFAULT_SITE = old_add_default_site
|
||||
|
||||
def test_load_templates(self):
|
||||
result = loader.get_template("base.html").render(Context({}))
|
||||
result = loader.get_template("base.html").render()
|
||||
self.assertEqual(result, 'base')
|
||||
result2 = loader.get_template("sub.html").render(Context({}))
|
||||
result2 = loader.get_template("sub.html").render()
|
||||
self.assertEqual(result2, 'sub')
|
||||
|
||||
def test_error_templates_creation(self):
|
||||
|
|
@ -99,17 +99,17 @@ class DbTemplatesTestCase(TestCase):
|
|||
self.assertEqual(admin_base_template, template.content)
|
||||
|
||||
def test_sync_templates(self):
|
||||
old_template_dirs = settings.TEMPLATE_DIRS
|
||||
old_template_dirs = settings.TEMPLATES[0].get('DIRS', [])
|
||||
temp_template_dir = tempfile.mkdtemp('dbtemplates')
|
||||
temp_template_path = os.path.join(temp_template_dir, 'temp_test.html')
|
||||
temp_template = codecs.open(temp_template_path, 'w')
|
||||
temp_template = io.open(temp_template_path, 'w', encoding='utf-8')
|
||||
try:
|
||||
temp_template.write('temp test')
|
||||
settings.TEMPLATE_DIRS = (temp_template_dir,)
|
||||
temp_template.write(u'temp test')
|
||||
settings.TEMPLATES[0]['DIRS'] = (temp_template_dir,)
|
||||
# these works well if is not settings patched at runtime
|
||||
# for supporting django < 1.7 tests we must patch dirs in runtime
|
||||
from dbtemplates.management.commands import sync_templates
|
||||
sync_templates.DIRS = settings.TEMPLATE_DIRS
|
||||
sync_templates.DIRS = settings.TEMPLATES[0]['DIRS']
|
||||
|
||||
self.assertFalse(
|
||||
Template.objects.filter(name='temp_test.html').exists())
|
||||
|
|
@ -119,12 +119,13 @@ class DbTemplatesTestCase(TestCase):
|
|||
Template.objects.filter(name='temp_test.html').exists())
|
||||
|
||||
t = Template.objects.get(name='temp_test.html')
|
||||
t.content = 'temp test modified'
|
||||
t.content = u'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.assertEqual(u'temp test modified',
|
||||
io.open(temp_template_path,
|
||||
encoding='utf-8').read())
|
||||
|
||||
call_command('sync_templates', force=True, verbosity=0,
|
||||
delete=True, overwrite=DATABASE_TO_FILES)
|
||||
|
|
@ -133,7 +134,7 @@ class DbTemplatesTestCase(TestCase):
|
|||
Template.objects.filter(name='temp_test.html').exists())
|
||||
finally:
|
||||
temp_template.close()
|
||||
settings.TEMPLATE_DIRS = old_template_dirs
|
||||
settings.TEMPLATES[0]['DIRS'] = old_template_dirs
|
||||
shutil.rmtree(temp_template_dir)
|
||||
|
||||
def test_get_cache(self):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
|
||||
import django
|
||||
|
||||
DBTEMPLATES_CACHE_BACKEND = 'dummy://'
|
||||
|
||||
DATABASE_ENGINE = 'sqlite3'
|
||||
|
|
@ -37,5 +34,11 @@ TEMPLATE_LOADERS = (
|
|||
'dbtemplates.loader.Loader',
|
||||
)
|
||||
|
||||
if django.get_version() <= '1.6':
|
||||
TEST_RUNNER = 'discover_runner.DiscoverRunner'
|
||||
TEMPLATES = [
|
||||
{
|
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||||
'OPTIONS': {
|
||||
'loaders': TEMPLATE_LOADERS,
|
||||
}
|
||||
},
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,16 +9,10 @@ def get_cache_backend():
|
|||
"""
|
||||
Compatibilty wrapper for getting Django's cache backend instance
|
||||
"""
|
||||
try:
|
||||
from django.core.cache import _create_cache
|
||||
except ImportError:
|
||||
# Django < 1.7
|
||||
from django.core.cache import get_cache as _get_cache
|
||||
return _get_cache(settings.DBTEMPLATES_CACHE_BACKEND)
|
||||
|
||||
cache = _create_cache(settings.DBTEMPLATES_CACHE_BACKEND)
|
||||
# Some caches -- python-memcached in particular -- need to do a cleanup at the
|
||||
# end of a request cycle. If not implemented in a particular backend
|
||||
# Some caches -- python-memcached in particular -- need to do a cleanup at
|
||||
# the end of a request cycle. If not implemented in a particular backend
|
||||
# cache.close is a no-op
|
||||
signals.request_finished.connect(cache.close)
|
||||
return cache
|
||||
|
|
|
|||
|
|
@ -1,24 +1,9 @@
|
|||
from django import VERSION
|
||||
from django.template import (Template, TemplateDoesNotExist,
|
||||
TemplateSyntaxError)
|
||||
from importlib import import_module
|
||||
|
||||
|
||||
def get_loaders():
|
||||
if VERSION[:2] < (1, 8):
|
||||
from django.template.loader import template_source_loaders
|
||||
if template_source_loaders is None:
|
||||
try:
|
||||
from django.template.loader import find_template as finder
|
||||
except ImportError:
|
||||
from django.template.loader import find_template_source as finder # noqa
|
||||
try:
|
||||
source, name = finder('test')
|
||||
except TemplateDoesNotExist:
|
||||
pass
|
||||
from django.template.loader import template_source_loaders
|
||||
return template_source_loaders or []
|
||||
else:
|
||||
from django.template.loader import _engine_list
|
||||
loaders = []
|
||||
for engine in _engine_list():
|
||||
|
|
@ -45,15 +30,6 @@ def get_template_source(name):
|
|||
pass
|
||||
except TemplateDoesNotExist:
|
||||
pass
|
||||
if source is None and VERSION[:2] < (1, 2):
|
||||
# Django supported template source extraction still :/
|
||||
try:
|
||||
from django.template.loader import find_template_source
|
||||
template, origin = find_template_source(name, None)
|
||||
if not hasattr(template, 'render'):
|
||||
return template
|
||||
except (ImportError, TemplateDoesNotExist):
|
||||
pass
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,21 @@
|
|||
Changelog
|
||||
=========
|
||||
|
||||
v1.4 (unreleased)
|
||||
v2.0 (unreleased)
|
||||
-----------------
|
||||
|
||||
* Moved to Jazzband: https://github.com/jazzband/django-dbtemplates
|
||||
|
||||
* Dropped support for Python 2.6
|
||||
|
||||
* Added support for Python 3.4 and 3.5
|
||||
|
||||
* Dropped support for Django < 1.8
|
||||
|
||||
* Removed South migrations. Please use Django's native migration system instead
|
||||
|
||||
* Removed the example project since it's out-of-date quickly
|
||||
|
||||
v1.3.2 (2015-06-15)
|
||||
-------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
import os, sys
|
||||
from django.core.management import execute_manager
|
||||
|
||||
sys.path.insert(0, os.path.abspath('./..'))
|
||||
|
||||
try:
|
||||
import settings # Assumed to be in the same directory.
|
||||
except ImportError:
|
||||
import sys
|
||||
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
execute_manager(settings)
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
south
|
||||
django>=1.3
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
# Django settings for example project.
|
||||
import os, posixpath
|
||||
|
||||
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
DEBUG = True
|
||||
TEMPLATE_DEBUG = DEBUG
|
||||
|
||||
ADMINS = (
|
||||
# ('Your Name', 'your_email@domain.com'),
|
||||
)
|
||||
|
||||
MANAGERS = ADMINS
|
||||
|
||||
DATABASE_ENGINE = 'sqlite3' # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
|
||||
DATABASE_NAME = 'example.db' # Or path to database file if using sqlite3.
|
||||
DATABASE_USER = '' # Not used with sqlite3.
|
||||
DATABASE_PASSWORD = '' # Not used with sqlite3.
|
||||
DATABASE_HOST = '' # Set to empty string for localhost. Not used with sqlite3.
|
||||
DATABASE_PORT = '' # Set to empty string for default. Not used with sqlite3.
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.sqlite3",
|
||||
"NAME": DATABASE_NAME,
|
||||
}
|
||||
}
|
||||
|
||||
# Local time zone for this installation. Choices can be found here:
|
||||
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
|
||||
# although not all choices may be available on all operating systems.
|
||||
# If running in a Windows environment this must be set to the same as your
|
||||
# system time zone.
|
||||
TIME_ZONE = 'America/Chicago'
|
||||
|
||||
# Language code for this installation. All choices can be found here:
|
||||
# http://www.i18nguy.com/unicode/language-identifiers.html
|
||||
LANGUAGE_CODE = 'en-us'
|
||||
|
||||
SITE_ID = 1
|
||||
|
||||
# If you set this to False, Django will make some optimizations so as not
|
||||
# to load the internationalization machinery.
|
||||
USE_I18N = True
|
||||
|
||||
# Absolute path to the directory that holds media.
|
||||
# Example: "/home/media/media.lawrence.com/"
|
||||
MEDIA_ROOT = os.path.join(PROJECT_ROOT, "site_media", "media")
|
||||
|
||||
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
|
||||
# trailing slash if there is a path component (optional in other cases).
|
||||
# Examples: "http://media.lawrence.com", "http://example.com/media/"
|
||||
MEDIA_URL = "/site_media/media/"
|
||||
|
||||
# Absolute path to the directory that holds static files like app media.
|
||||
# Example: "/home/media/media.lawrence.com/apps/"
|
||||
STATIC_ROOT = os.path.join(PROJECT_ROOT, "site_media", "static")
|
||||
|
||||
# URL that handles the static files like app media.
|
||||
# Example: "http://media.lawrence.com"
|
||||
STATIC_URL = "/site_media/static/"
|
||||
|
||||
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
|
||||
# trailing slash.
|
||||
# Examples: "http://foo.com/media/", "/media/".
|
||||
ADMIN_MEDIA_PREFIX = posixpath.join(STATIC_URL, "admin/")
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
SECRET_KEY = 'e-%(1e1f8ar2v)_8d!%-75a2ag(w(ht*l%n-wts5$li!5=97)8'
|
||||
|
||||
# List of callables that know how to import templates from various sources.
|
||||
TEMPLATE_LOADERS = (
|
||||
'django.template.loaders.filesystem.Loader',
|
||||
'django.template.loaders.app_directories.Loader',
|
||||
'django.template.loaders.eggs.Loader',
|
||||
'dbtemplates.loader.Loader',
|
||||
)
|
||||
|
||||
MIDDLEWARE_CLASSES = (
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
|
||||
)
|
||||
|
||||
ROOT_URLCONF = 'example.urls'
|
||||
|
||||
TEMPLATE_DIRS = (
|
||||
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
|
||||
# Always use forward slashes, even on Windows.
|
||||
# Don't forget to use absolute paths, not relative paths.
|
||||
)
|
||||
|
||||
INSTALLED_APPS = (
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
'django.contrib.admin',
|
||||
'django.contrib.flatpages',
|
||||
'django.contrib.staticfiles',
|
||||
'dbtemplates',
|
||||
'south',
|
||||
#'reversion',
|
||||
)
|
||||
|
||||
# Uncomment the following two settings to use the file system cache backend.
|
||||
# It will cache in the directory "cache" inside the example project directory.
|
||||
DBTEMPLATES_CACHE_BACKEND = "locmem://"
|
||||
|
||||
DBTEMPLATES_MEDIA_PREFIX = posixpath.join(STATIC_URL, "dbtemplates/")
|
||||
DBTEMPLATES_USE_CODEMIRROR = True
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
from django.conf import settings
|
||||
from django.conf.urls.defaults import patterns, include
|
||||
|
||||
# Uncomment the next two lines to enable the admin:
|
||||
from django.contrib import admin
|
||||
admin.autodiscover()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
# Example:
|
||||
# (r'^example/', include('example.foo.urls')),
|
||||
|
||||
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
|
||||
# to INSTALLED_APPS to enable admin documentation:
|
||||
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
|
||||
|
||||
# Uncomment the next line to enable the admin:
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
)
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
flake8<3
|
||||
django-discover-runner
|
||||
flake8
|
||||
coverage
|
||||
|
|
|
|||
33
setup.py
33
setup.py
|
|
@ -1,22 +1,28 @@
|
|||
import ast
|
||||
import os
|
||||
import re
|
||||
import codecs
|
||||
import io
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
|
||||
class VersionFinder(ast.NodeVisitor):
|
||||
def __init__(self):
|
||||
self.version = None
|
||||
|
||||
def visit_Assign(self, node):
|
||||
if node.targets[0].id == '__version__':
|
||||
self.version = node.value.s
|
||||
|
||||
|
||||
def read(*parts):
|
||||
filename = os.path.join(os.path.dirname(__file__), *parts)
|
||||
with codecs.open(filename, encoding='utf-8') as fp:
|
||||
with io.open(filename, encoding='utf-8') as fp:
|
||||
return fp.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.")
|
||||
def find_version(*parts):
|
||||
finder = VersionFinder()
|
||||
finder.visit(ast.parse(read(*parts)))
|
||||
return finder.version
|
||||
|
||||
|
||||
setup(
|
||||
|
|
@ -27,7 +33,7 @@ setup(
|
|||
author='Jannis Leidel',
|
||||
author_email='jannis@leidel.info',
|
||||
url='https://django-dbtemplates.readthedocs.io/',
|
||||
packages=find_packages(exclude=['example']),
|
||||
packages=find_packages(),
|
||||
zip_safe=False,
|
||||
package_data={
|
||||
'dbtemplates': [
|
||||
|
|
@ -44,9 +50,10 @@ setup(
|
|||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.5',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Framework :: Django',
|
||||
],
|
||||
install_requires=['django-appconf >= 0.4'],
|
||||
|
|
|
|||
46
tox.ini
Normal file
46
tox.ini
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
[tox]
|
||||
skipsdist = True
|
||||
usedevelop = True
|
||||
minversion = 1.8
|
||||
envlist =
|
||||
flake8-py27,
|
||||
flake8-py35,
|
||||
readme-py27,
|
||||
py{27,34,35,py}-dj{18,19,110,master}
|
||||
|
||||
[testenv]
|
||||
basepython =
|
||||
py27: python2.7
|
||||
py34: python3.4
|
||||
py35: python3.5
|
||||
pypy: pypy
|
||||
usedevelop = true
|
||||
setenv =
|
||||
DJANGO_SETTINGS_MODULE = dbtemplates.test_settings
|
||||
deps =
|
||||
-rrequirements/tests.txt
|
||||
dj18: https://github.com/django/django/archive/stable/1.8.x.tar.gz#egg=django
|
||||
dj19: https://github.com/django/django/archive/stable/1.9.x.tar.gz#egg=django
|
||||
dj110: https://github.com/django/django/archive/stable/1.10.x.tar.gz#egg=django
|
||||
djmaster: https://github.com/django/django/archive/master.tar.gz#egg=django
|
||||
|
||||
commands =
|
||||
python --version
|
||||
coverage run {envbindir}/django-admin.py test -v2 {posargs:dbtemplates}
|
||||
coverage report
|
||||
|
||||
[testenv:readme-py27]
|
||||
commands = python setup.py check -r -s
|
||||
deps = readme_renderer
|
||||
|
||||
[testenv:flake8-py27]
|
||||
commands = flake8 dbtemplates
|
||||
deps = flake8
|
||||
|
||||
[testenv:flake8-py35]
|
||||
commands = flake8 dbtemplates
|
||||
deps = flake8
|
||||
|
||||
[flake8]
|
||||
exclude=.tox
|
||||
ignore=E501,E127,E128,E124
|
||||
Loading…
Reference in a new issue