From 92d50c6abe1578045de00ccc0ab31e264906a79b Mon Sep 17 00:00:00 2001 From: Park Hyunwoo Date: Sat, 1 Sep 2018 15:48:23 +0900 Subject: [PATCH] Shape up config things --- django_summernote/admin.py | 4 ++-- django_summernote/apps.py | 5 ++-- django_summernote/tests.py | 17 ++++++++------ django_summernote/utils.py | 45 +++++++++++++++++++++++++++++++++--- django_summernote/views.py | 9 ++++---- django_summernote/widgets.py | 10 ++++---- 6 files changed, 66 insertions(+), 24 deletions(-) diff --git a/django_summernote/admin.py b/django_summernote/admin.py index 73b29d5a6..243aae8e 100644 --- a/django_summernote/admin.py +++ b/django_summernote/admin.py @@ -2,15 +2,15 @@ from django.contrib import admin from django.contrib.admin.options import InlineModelAdmin from django.db import models -from django_summernote.utils import get_attachment_model +from django_summernote.utils import get_attachment_model, using_config from django_summernote.widgets import SummernoteWidget, SummernoteInplaceWidget class SummernoteModelAdminMixin(object): summernote_fields = '__all__' + @using_config def formfield_for_dbfield(self, db_field, *args, **kwargs): - config = apps.get_app_config('django_summernote').config summernote_widget = SummernoteWidget if config['iframe'] else SummernoteInplaceWidget if self.summernote_fields == '__all__': diff --git a/django_summernote/apps.py b/django_summernote/apps.py index f78fad18..e07a693f 100644 --- a/django_summernote/apps.py +++ b/django_summernote/apps.py @@ -14,7 +14,7 @@ class DjangoSummernoteConfig(AppConfig): def __init__(self, app_name, app_module): super(DjangoSummernoteConfig, self).__init__(app_name, app_module) - self.merge_config() + self.update_config() def get_default_config(self): return { @@ -106,9 +106,10 @@ def _copy_old_configs(self, user, default): if not self.config['summernote'].get(key): self.config['summernote'][key] = default['summernote'].get(key) - def merge_config(self): + def update_config(self): DEFAULT_CONFIG = self.get_default_config() CONFIG = getattr(django_settings, 'SUMMERNOTE_CONFIG', {}) + self.theme = getattr(django_settings, 'SUMMERNOTE_THEME', 'bs3') self.config = DEFAULT_CONFIG.copy() self.config.update(CONFIG) diff --git a/django_summernote/tests.py b/django_summernote/tests.py index c7133ec3..e82ed257 100644 --- a/django_summernote/tests.py +++ b/django_summernote/tests.py @@ -19,8 +19,9 @@ def setUp(self): self.username = 'lqez' self.password = 'ohmygoddess' self.site = AdminSite() - self.config = apps.get_app_config('django_summernote') - self.summernote_config = self.config.config + + self.app_config = apps.get_app_config('django_summernote') + self.summernote_config = self.app_config.config def test_base(self): self.assertTrue(True) @@ -457,7 +458,7 @@ def test_old_style_configs(self): ['font', ['bold']], ], } - self.config._copy_old_configs(OLD_STYLE_CONFIG, self.config.get_default_config()) + self.app_config._copy_old_configs(OLD_STYLE_CONFIG, self.app_config.get_default_config()) widget = SummernoteInplaceWidget() html = widget.render( @@ -488,8 +489,10 @@ def test_theme_bootstrap3(self): def test_theme_bootstrap4(self): from django_summernote.utils import SUMMERNOTE_THEME_FILES - self.config.theme = 'bs4' - self.config.merge_config() + old_theme = self.app_config.theme + + self.app_config.theme = 'bs4' + self.app_config.update_config() url = reverse('django_summernote-editor', kwargs={'id': 'id_foobar'}) response = self.client.get(url) @@ -497,5 +500,5 @@ def test_theme_bootstrap4(self): assert SUMMERNOTE_THEME_FILES['bs4']['base_css'][0] in html - self.config.theme = 'bs3' - self.config.merge_config() + self.app_config.theme = old_theme + self.app_config.update_config() diff --git a/django_summernote/utils.py b/django_summernote/utils.py index 61286ad7..2e987626 100644 --- a/django_summernote/utils.py +++ b/django_summernote/utils.py @@ -5,9 +5,11 @@ from django.core.exceptions import ImproperlyConfigured from django.core.files.storage import default_storage from django.utils.translation import get_language +from functools import wraps from importlib import import_module +# A conversion table from language to locale LANG_TO_LOCALE = { 'ar': 'ar-AR', 'bg': 'bg-BG', @@ -50,6 +52,7 @@ 'zh': 'zh-CN', } +# Theme files dictionary SUMMERNOTE_THEME_FILES = { 'bs3': { 'base_css': ( @@ -111,6 +114,38 @@ } +def using_config(_func=None): + """ + This allows a function to use Summernote configuration + as a global variable, temporarily. + """ + def decorator(func): + @wraps(func) + def inner_dec(*args, **kwargs): + g = func.__globals__ + var_name = 'config' + sentinel = object() + + oldvalue = g.get(var_name, sentinel) + g[var_name] = apps.get_app_config('django_summernote').config + + try: + res = func(*args, **kwargs) + finally: + if oldvalue is sentinel: + del g[var_name] + else: + g[var_name] = oldvalue + + return res + return inner_dec + + if _func is None: + return decorator + else: + return decorator(_func) + + def uploaded_filepath(instance, filename): """ Returns default filepath for uploaded files. @@ -128,11 +163,11 @@ def get_theme_files(theme, part): return SUMMERNOTE_THEME_FILES[theme][part] +@using_config def get_proper_language(): """ Return the proper language by get_language() """ - config = apps.get_app_config('django_summernote').config lang = config['summernote'].get('lang') if not lang: @@ -141,11 +176,11 @@ def get_proper_language(): return lang +@using_config def get_attachment_model(): """ Returns the Attachment model that is active in this project. """ - config = apps.get_app_config('django_summernote').config try: from .models import AbstractAttachment @@ -164,11 +199,15 @@ def get_attachment_model(): ) +@using_config def get_attachment_upload_to(): - config = apps.get_app_config('django_summernote').config + """ + Return 'attachment_upload_to' from configuration + """ return config['attachment_upload_to'] +@using_config def get_attachment_storage(): # module importer code comes from # https://github.com/django-debug-toolbar/django-debug-toolbar/ diff --git a/django_summernote/views.py b/django_summernote/views.py index f093c556..faf126f2 100644 --- a/django_summernote/views.py +++ b/django_summernote/views.py @@ -5,7 +5,7 @@ from django.template.loader import render_to_string from django.utils.translation import ugettext as _ from django.views.generic import TemplateView -from django_summernote.utils import get_attachment_model +from django_summernote.utils import get_attachment_model, using_config if django.VERSION <= (1, 9): from django.views.generic import View else: @@ -15,11 +15,10 @@ class SummernoteEditor(TemplateView): template_name = 'django_summernote/widget_iframe_editor.html' + @using_config def __init__(self): super(SummernoteEditor, self).__init__() - config = apps.get_app_config('django_summernote').config - static_default_css = tuple(static(x) for x in config['default_css']) static_default_js = tuple(static(x) for x in config['default_js']) @@ -35,9 +34,9 @@ def __init__(self): + (config['codemirror_js'] if 'codemirror' in config else ()) \ + static_default_js + @using_config def get_context_data(self, **kwargs): context = super(SummernoteEditor, self).get_context_data(**kwargs) - config = apps.get_app_config('django_summernote').config context['id_src'] = self.kwargs['id'] context['id'] = self.kwargs['id'].replace('-', '_') @@ -58,11 +57,11 @@ def get(self, request, *args, **kwargs): 'message': _('Only POST method is allowed'), }, status=400) + @using_config def post(self, request, *args, **kwargs): authenticated = \ request.user.is_authenticated if django.VERSION >= (1, 10) \ else request.user.is_authenticated() - config = apps.get_app_config('django_summernote').config if config['attachment_require_authentication'] and \ not authenticated: diff --git a/django_summernote/widgets.py b/django_summernote/widgets.py index e0388361..63656be8 100644 --- a/django_summernote/widgets.py +++ b/django_summernote/widgets.py @@ -6,7 +6,7 @@ from django.forms.utils import flatatt from django.template.loader import render_to_string from django.utils.safestring import mark_safe -from django_summernote.utils import get_proper_language +from django_summernote.utils import get_proper_language, using_config try: from django.urls import reverse # Django >= 2.0 except ImportError: @@ -16,9 +16,9 @@ class SummernoteWidgetBase(forms.Textarea): + @using_config def summernote_settings(self): lang = get_proper_language() - config = apps.get_app_config('django_summernote').config summernote_settings = config.get('summernote', {}).copy() summernote_settings.update({ @@ -30,10 +30,10 @@ def summernote_settings(self): }) return summernote_settings + @using_config def value_from_datadict(self, data, files, name): value = data.get(name, None) - config = apps.get_app_config('django_summernote').config if value in config['empty']: return None @@ -71,8 +71,8 @@ def render(self, name, value, attrs=None, **kwargs): class SummernoteInplaceWidget(SummernoteWidgetBase): + @using_config def _media(self): - config = apps.get_app_config('django_summernote').config return forms.Media( css={ 'all': ( @@ -89,8 +89,8 @@ def _media(self): media = property(_media) + @using_config def render(self, name, value, attrs=None, **kwargs): - config = apps.get_app_config('django_summernote').config summernote_settings = self.summernote_settings() summernote_settings.update(self.attrs.pop('summernote', {}))