Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 79 additions & 54 deletions dbtemplates/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,30 @@
# 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:
from django.contrib.admin import ModelAdmin as TemplateModelAdmin # noqa


class CodeMirrorTextArea(forms.Textarea):

"""
A custom widget for the CodeMirror browser editor to be used with the
content field of the Template model.
"""

class Media:
css = dict(screen=[posixpath.join(
settings.DBTEMPLATES_MEDIA_PREFIX, 'css/editor.css')])
js = [posixpath.join(settings.DBTEMPLATES_MEDIA_PREFIX,
'js/codemirror.js')]
css = dict(
screen=[posixpath.join(settings.DBTEMPLATES_MEDIA_PREFIX, "css/editor.css")]
)
js = [posixpath.join(settings.DBTEMPLATES_MEDIA_PREFIX, "js/codemirror.js")]

def render(self, name, value, attrs=None, renderer=None):
result = []
result.append(super().render(name, value, attrs))
result.append(
super().render(name, value, attrs))
result.append("""
"""
<script type="text/javascript">
var editor = CodeMirror.fromTextArea('id_%(name)s', {
path: "%(media_prefix)sjs/",
Expand All @@ -51,7 +50,9 @@ def render(self, name, value, attrs=None, renderer=None):
lineNumbers: true
});
</script>
""" % dict(media_prefix=settings.DBTEMPLATES_MEDIA_PREFIX, name=name))
"""
% dict(media_prefix=settings.DBTEMPLATES_MEDIA_PREFIX, name=name)
)
return mark_safe("".join(result))


Expand All @@ -61,62 +62,79 @@ def render(self, name, value, attrs=None, renderer=None):
TemplateContentTextArea = forms.Textarea

if settings.DBTEMPLATES_AUTO_POPULATE_CONTENT:
content_help_text = _("Leaving this empty causes Django to look for a "
"template with the given name and populate this "
"field with its content.")
content_help_text = _(
"Leaving this empty causes Django to look for a "
"template with the given name and populate this "
"field with its 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.")
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
elif settings.DBTEMPLATES_USE_REDACTOR:
from redactor.widgets import RedactorEditor

TemplateContentTextArea = RedactorEditor


class TemplateAdminForm(forms.ModelForm):

"""
Custom AdminForm to make the content textarea wider.
"""

content = forms.CharField(
widget=TemplateContentTextArea(attrs={'rows': '24'}),
help_text=content_help_text, required=False)
widget=TemplateContentTextArea(attrs={"rows": "24"}),
help_text=content_help_text,
required=False,
)

class Meta:
model = Template
fields = ('name', 'content', 'sites', 'creation_date', 'last_changed')
fields = ("name", "content", "sites", "creation_date", "last_changed")
fields = "__all__"


class TemplateAdmin(TemplateModelAdmin):
form = TemplateAdminForm
readonly_fields = ['creation_date', 'last_changed']
readonly_fields = ["creation_date", "last_changed"]
fieldsets = (
(None, {
'fields': ('name', 'content'),
'classes': ('monospace',),
}),
(_('Advanced'), {
'fields': (('sites'),),
}),
(_('Date/time'), {
'fields': (('creation_date', 'last_changed'),),
'classes': ('collapse',),
}),
(
None,
{
"fields": ("name", "content"),
"classes": ("monospace",),
},
),
(
_("Advanced"),
{
"fields": (("sites"),),
},
),
(
_("Date/time"),
{
"fields": (("creation_date", "last_changed"),),
"classes": ("collapse",),
},
),
)
filter_horizontal = ('sites',)
list_display = ('name', 'creation_date', 'last_changed', 'site_list')
list_filter = ('sites',)
filter_horizontal = ("sites",)
list_display = ("name", "creation_date", "last_changed", "site_list")
list_filter = ("sites",)
save_as = True
search_fields = ('name', 'content')
actions = ['invalidate_cache', 'repopulate_cache', 'check_syntax']
search_fields = ("name", "content")
actions = ["invalidate_cache", "repopulate_cache", "check_syntax"]

def invalidate_cache(self, request, queryset):
for template in queryset:
Expand All @@ -125,10 +143,11 @@ def invalidate_cache(self, request, queryset):
message = ngettext(
"Cache of one template successfully invalidated.",
"Cache of %(count)d templates successfully invalidated.",
count)
self.message_user(request, message % {'count': count})
invalidate_cache.short_description = _("Invalidate cache of "
"selected templates")
count,
)
self.message_user(request, message % {"count": count})

invalidate_cache.short_description = _("Invalidate cache of selected templates")

def repopulate_cache(self, request, queryset):
for template in queryset:
Expand All @@ -137,37 +156,43 @@ def repopulate_cache(self, request, queryset):
message = ngettext(
"Cache successfully repopulated with one template.",
"Cache successfully repopulated with %(count)d templates.",
count)
self.message_user(request, message % {'count': count})
repopulate_cache.short_description = _("Repopulate cache with "
"selected templates")
count,
)
self.message_user(request, message % {"count": count})

repopulate_cache.short_description = _("Repopulate cache with selected templates")

def check_syntax(self, request, queryset):
errors = []
for template in queryset:
valid, error = check_template_syntax(template)
if not valid:
errors.append(f'{template.name}: {error}')
errors.append(f"{template.name}: {error}")
if errors:
count = len(errors)
message = ngettext(
"Template syntax check FAILED for %(names)s.",
"Template syntax check FAILED for "
"%(count)d templates: %(names)s.",
count)
self.message_user(request, message %
{'count': count, 'names': ', '.join(errors)})
"Template syntax check FAILED for %(count)d templates: %(names)s.",
count,
)
self.message_user(
request, message % {"count": count, "names": ", ".join(errors)}
)
else:
count = queryset.count()
message = ngettext(
"Template syntax OK.",
"Template syntax OK for %(count)d templates.", count)
self.message_user(request, message % {'count': count})
"Template syntax OK for %(count)d templates.",
count,
)
self.message_user(request, message % {"count": count})

check_syntax.short_description = _("Check template syntax")

def site_list(self, template):
return ", ".join([site.name for site in template.sites.all()])
site_list.short_description = _('sites')

site_list.short_description = _("sites")


admin.site.register(Template, TemplateAdmin)
6 changes: 3 additions & 3 deletions dbtemplates/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@


class DBTemplatesConfig(AppConfig):
name = 'dbtemplates'
verbose_name = _('Database templates')
name = "dbtemplates"
verbose_name = _("Database templates")

default_auto_field = 'django.db.models.AutoField'
default_auto_field = "django.db.models.AutoField"
48 changes: 29 additions & 19 deletions dbtemplates/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,35 +33,45 @@ def configure_cache_backend(self, value):
else:
return "default"
if isinstance(value, str) and value.startswith("dbtemplates."):
raise ImproperlyConfigured("Please upgrade to one of the "
"supported backends as defined "
"in the Django docs.")
raise ImproperlyConfigured(
"Please upgrade to one of the "
"supported backends as defined "
"in the Django docs."
)
return value

def configure_use_reversion(self, value):
if value and 'reversion' not in settings.INSTALLED_APPS:
raise ImproperlyConfigured("Please add 'reversion' to your "
"INSTALLED_APPS setting to make "
"use of it in dbtemplates.")
if value and "reversion" not in settings.INSTALLED_APPS:
raise ImproperlyConfigured(
"Please add 'reversion' to your "
"INSTALLED_APPS setting to make "
"use of it in dbtemplates."
)
return value

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 "
"use of it in dbtemplates.")
if value and "reversion_compare" not in settings.INSTALLED_APPS:
raise ImproperlyConfigured(
"Please add 'reversion_compare' 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.")
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

def configure_use_redactor(self, value):
if value and 'redactor' not in settings.INSTALLED_APPS:
raise ImproperlyConfigured("Please add 'redactor' to your "
"INSTALLED_APPS setting to make "
"use of it in dbtemplates.")
if value and "redactor" not in settings.INSTALLED_APPS:
raise ImproperlyConfigured(
"Please add 'redactor' to your "
"INSTALLED_APPS setting to make "
"use of it in dbtemplates."
)
return value
Loading
Loading