diff --git a/dbtemplates/admin.py b/dbtemplates/admin.py index bb079bb..9bfefa7 100644 --- a/dbtemplates/admin.py +++ b/dbtemplates/admin.py @@ -5,7 +5,8 @@ from django.core.exceptions import ImproperlyConfigured try: from django.utils.translation import ungettext, ugettext_lazy as _ except ImportError: - from django.utils.translation import ngettext, gettext_lazy as _ + from django.utils.translation import ngettext as ungettext, \ + gettext_lazy as _ from django.utils.safestring import mark_safe from dbtemplates.conf import settings @@ -17,7 +18,8 @@ from dbtemplates.utils.template import check_template_syntax # use reversion_compare's CompareVersionAdmin or reversion's VersionAdmin as # the base admin class if yes if settings.DBTEMPLATES_USE_REVERSION_COMPARE: - from reversion_compare.admin import CompareVersionAdmin as TemplateModelAdmin + from reversion_compare.admin import CompareVersionAdmin \ + as TemplateModelAdmin elif settings.DBTEMPLATES_USE_REVERSION: from reversion.admin import VersionAdmin as TemplateModelAdmin else: @@ -33,7 +35,8 @@ class CodeMirrorTextArea(forms.Textarea): class Media: css = dict(screen=[posixpath.join( settings.DBTEMPLATES_MEDIA_PREFIX, 'css/editor.css')]) - js = [posixpath.join(settings.DBTEMPLATES_MEDIA_PREFIX, 'js/codemirror.js')] + js = [posixpath.join(settings.DBTEMPLATES_MEDIA_PREFIX, + 'js/codemirror.js')] def render(self, name, value, attrs=None, renderer=None): result = [] @@ -152,7 +155,8 @@ class TemplateAdmin(TemplateModelAdmin): count = len(errors) message = ungettext( "Template syntax check FAILED for %(names)s.", - "Template syntax check FAILED for %(count)d templates: %(names)s.", + "Template syntax check FAILED for " + "%(count)d templates: %(names)s.", count) self.message_user(request, message % {'count': count, 'names': ', '.join(errors)}) diff --git a/dbtemplates/apps.py b/dbtemplates/apps.py index 9b16d38..21141b3 100644 --- a/dbtemplates/apps.py +++ b/dbtemplates/apps.py @@ -4,6 +4,7 @@ try: except ImportError: from django.utils.translation import gettext_lazy as _ + class DBTemplatesConfig(AppConfig): name = 'dbtemplates' verbose_name = _('Database templates') diff --git a/dbtemplates/conf.py b/dbtemplates/conf.py index 8b8809a..010db5b 100644 --- a/dbtemplates/conf.py +++ b/dbtemplates/conf.py @@ -47,8 +47,8 @@ class DbTemplatesConf(AppConf): def configure_use_reversion_compare(self, value): if value and 'reversion_compare' not in settings.INSTALLED_APPS: - raise ImproperlyConfigured("Please add 'reversion_compare' to your " - "INSTALLED_APPS setting to make " + raise ImproperlyConfigured("Please add 'reversion_compare' to your" + " INSTALLED_APPS setting to make " "use of it in dbtemplates.") return value diff --git a/dbtemplates/loader.py b/dbtemplates/loader.py index 403c460..5a57f27 100644 --- a/dbtemplates/loader.py +++ b/dbtemplates/loader.py @@ -30,7 +30,8 @@ class Loader(BaseLoader): content, _ = self._load_template_source(origin.template_name) return content - def _load_and_store_template(self, template_name, cache_key, site, **params): + 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 = f'dbtemplates:{db}:{template_name}:{site.domain}' @@ -73,11 +74,11 @@ class Loader(BaseLoader): try: return self._load_and_store_template(template_name, cache_key, - site, sites__in=[site.id]) + site, sites__in=[site.id]) except (Template.MultipleObjectsReturned, Template.DoesNotExist): try: return self._load_and_store_template(template_name, cache_key, - site, sites__isnull=True) + site, sites__isnull=True) except (Template.MultipleObjectsReturned, Template.DoesNotExist): pass diff --git a/dbtemplates/management/commands/sync_templates.py b/dbtemplates/management/commands/sync_templates.py index b01e61e..7e336e0 100644 --- a/dbtemplates/management/commands/sync_templates.py +++ b/dbtemplates/management/commands/sync_templates.py @@ -1,18 +1,18 @@ import os -from django.contrib.sites.models import Site -from django.core.management.base import CommandError, BaseCommand -from django.template.utils import get_app_template_dirs -from django.template.loader import _engine_list from dbtemplates.models import Template +from django.contrib.sites.models import Site +from django.core.management.base import BaseCommand, CommandError +from django.template.loader import _engine_list +from django.template.utils import get_app_template_dirs -ALWAYS_ASK, FILES_TO_DATABASE, DATABASE_TO_FILES = ('0', '1', '2') +ALWAYS_ASK, FILES_TO_DATABASE, DATABASE_TO_FILES = ("0", "1", "2") DIRS = [] for engine in _engine_list(): DIRS.extend(engine.dirs) DIRS = tuple(DIRS) -app_template_dirs = get_app_template_dirs('templates') +app_template_dirs = get_app_template_dirs("templates") class Command(BaseCommand): @@ -20,36 +20,56 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument( - "-e", "--ext", - dest="ext", action="store", default="html", + "-e", + "--ext", + dest="ext", + action="store", + default="html", help="extension of the files you want to " - "sync with the database [default: %(default)s]") + "sync with the database [default: %(default)s]", + ) parser.add_argument( - "-f", "--force", - action="store_true", dest="force", default=False, - help="overwrite existing database templates") + "-f", + "--force", + action="store_true", + dest="force", + default=False, + help="overwrite existing database templates", + ) parser.add_argument( - "-o", "--overwrite", - action="store", dest="overwrite", default='0', + "-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") + "templates from template files, '2' - overwrite " + "template files from database templates", + ) parser.add_argument( - "-a", "--app-first", - action="store_true", dest="app_first", default=False, + "-a", + "--app-first", + action="store_true", + dest="app_first", + default=False, help="look for templates in applications " - "directories before project templates") + "directories before project templates", + ) parser.add_argument( - "-d", "--delete", - action="store_true", dest="delete", default=False, - help="Delete templates after syncing") + "-d", + "--delete", + action="store_true", + dest="delete", + default=False, + help="Delete templates after syncing", + ) def handle(self, **options): - extension = options.get('ext') - force = options.get('force') - overwrite = options.get('overwrite') - app_first = options.get('app_first') - delete = options.get('delete') + extension = options.get("ext") + force = options.get("force") + overwrite = options.get("overwrite") + app_first = options.get("app_first") + delete = options.get("delete") if not extension.startswith("."): extension = f".{extension}" @@ -57,8 +77,10 @@ class Command(BaseCommand): try: site = Site.objects.get_current() except Exception: - raise CommandError("Please make sure to have the sites contrib " - "app installed and setup with a site object") + raise CommandError( + "Please make sure to have the sites contrib " + "app installed and setup with a site object" + ) if app_first: tpl_dirs = app_template_dirs + DIRS @@ -68,11 +90,14 @@ class Command(BaseCommand): for templatedir in templatedirs: for dirpath, subdirs, filenames in os.walk(templatedir): - for f in [f for f in filenames - if f.endswith(extension) and not f.startswith(".")]: + for f in [ + f + for f in filenames + if f.endswith(extension) and not f.startswith(".") + ]: path = os.path.join(dirpath, f) name = path.split(str(templatedir))[1] - if name.startswith('/'): + if name.startswith("/"): name = name[1:] try: t = Template.on_site.get(name__exact=name) @@ -81,27 +106,35 @@ class Command(BaseCommand): confirm = input( "\nA '%s' template doesn't exist in the " "database.\nCreate it with '%s'?" - " (y/[n]): """ % (name, path)) - if force or confirm.lower().startswith('y'): - with open(path, encoding='utf-8') as f: + " (y/[n]): " + "" % (name, path) + ) + if force or confirm.lower().startswith("y"): + with open(path, encoding="utf-8") as f: t = Template(name=name, content=f.read()) t.save() t.sites.add(site) else: - while 1: + while True: if overwrite == ALWAYS_ASK: - confirm = input( + _i = ( "\n%(template)s exists in the database.\n" - "(1) Overwrite %(template)s with '%(path)s'\n" - "(2) Overwrite '%(path)s' with %(template)s\n" - "Type 1 or 2 or press to skip: " % - {'template': t.__repr__(), 'path': path}) + "(1) Overwrite %(template)s with '%(path)s'\n" # noqa + "(2) Overwrite '%(path)s' with %(template)s\n" # noqa + "Type 1 or 2 or press to skip: " + % {"template": t.__repr__(), "path": path} + ) + + confirm = input(_i) 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: - with open(path, encoding='utf-8') as f: + with open(path, encoding="utf-8") as f: t.content = f.read() t.save() t.sites.add(site) @@ -110,9 +143,10 @@ class Command(BaseCommand): os.remove(path) except OSError: raise CommandError( - f"Couldn't delete {path}") + f"Couldn't delete {path}" + ) elif confirm == DATABASE_TO_FILES: - with open(path, 'w', encoding='utf-8') as f: + with open(path, "w", encoding="utf-8") as f: # noqa f.write(t.content) if delete: t.delete() diff --git a/dbtemplates/migrations/0001_initial.py b/dbtemplates/migrations/0001_initial.py index 5d5b1f4..7ac217f 100644 --- a/dbtemplates/migrations/0001_initial.py +++ b/dbtemplates/migrations/0001_initial.py @@ -1,40 +1,73 @@ import django -from django.db import models, migrations import django.utils.timezone +from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('sites', '0001_initial'), + ("sites", "0001_initial"), ] operations = [ migrations.CreateModel( - name='Template', + 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)), + ( + "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), + ), # noqa + ( + "creation_date", + models.DateTimeField( + default=django.utils.timezone.now, + verbose_name="creation date", # noqa + ), + ), + ( + "last_changed", + models.DateTimeField( + default=django.utils.timezone.now, + verbose_name="last changed", # noqa + ), + ), + ( + "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', + "ordering": ("name",), + "db_table": "django_template", + "verbose_name": "template", + "verbose_name_plural": "templates", }, bases=(models.Model,), managers=[ - ('objects', django.db.models.manager.Manager()), - ('on_site', django.contrib.sites.managers.CurrentSiteManager('sites')), + ("objects", django.db.models.manager.Manager()), + ( + "on_site", + django.contrib.sites.managers.CurrentSiteManager("sites"), + ), # noqa ], ), ] diff --git a/dbtemplates/models.py b/dbtemplates/models.py index 2ca806b..42c03e2 100644 --- a/dbtemplates/models.py +++ b/dbtemplates/models.py @@ -11,7 +11,7 @@ try: from django.utils.translation import ugettext_lazy as _ except ImportError: from django.utils.translation import gettext_lazy as _ - + from django.utils.timezone import now diff --git a/dbtemplates/test_cases.py b/dbtemplates/test_cases.py index 8dc1363..ab553e5 100644 --- a/dbtemplates/test_cases.py +++ b/dbtemplates/test_cases.py @@ -125,7 +125,7 @@ class DbTemplatesTestCase(TestCase): verbosity=0, overwrite=DATABASE_TO_FILES) self.assertEqual('temp test modified', open(temp_template_path, - encoding='utf-8').read()) + encoding='utf-8').read()) call_command('sync_templates', force=True, verbosity=0, delete=True, overwrite=DATABASE_TO_FILES) diff --git a/dbtemplates/utils/cache.py b/dbtemplates/utils/cache.py index dd9d00f..32a0423 100644 --- a/dbtemplates/utils/cache.py +++ b/dbtemplates/utils/cache.py @@ -1,20 +1,23 @@ import django -from django.core import signals -from django.contrib.sites.models import Site -from django.template.defaultfilters import slugify - from dbtemplates.conf import settings +from django.contrib.sites.models import Site +from django.core import signals +from django.template.defaultfilters import slugify def get_cache_backend(): """ Compatibilty wrapper for getting Django's cache backend instance """ - if (django.VERSION[0] >= 3 and django.VERSION[1] >= 2) or django.VERSION[0] >= 4: + if (django.VERSION[0] >= 3 and django.VERSION[1] >= 2) or django.VERSION[ + 0 + ] >= 4: # noqa from django.core.cache import caches + cache = caches.create_connection(settings.DBTEMPLATES_CACHE_BACKEND) else: from django.core.cache import _create_cache + 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 @@ -28,11 +31,11 @@ cache = get_cache_backend() def get_cache_key(name): current_site = Site.objects.get_current() - return f'dbtemplates::{slugify(name)}::{current_site.pk}' + return f"dbtemplates::{slugify(name)}::{current_site.pk}" def get_cache_notfound_key(name): - return get_cache_key(name) + '::notfound' + return get_cache_key(name) + "::notfound" def remove_notfound_key(instance):