From faab1f2464ed2e4f9fdb03ce8a8ef4251004a120 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 15 Aug 2021 11:57:05 +1000 Subject: [PATCH 1/3] Provide global_settings and user_settings as context objects - Adds a new context middleware - Refactor the way that settings are provided to the javascript layer --- InvenTree/InvenTree/context.py | 22 ++++++++++ InvenTree/InvenTree/settings.py | 2 + InvenTree/common/models.py | 42 ++++++------------- .../part/templatetags/inventree_extras.py | 38 +++++++++-------- InvenTree/templates/js/dynamic/settings.js | 11 ++--- 5 files changed, 60 insertions(+), 55 deletions(-) diff --git a/InvenTree/InvenTree/context.py b/InvenTree/InvenTree/context.py index 3e1f98ffc2..6f59840967 100644 --- a/InvenTree/InvenTree/context.py +++ b/InvenTree/InvenTree/context.py @@ -10,6 +10,8 @@ from InvenTree.status_codes import StockHistoryCode import InvenTree.status +import common.models + from users.models import RuleSet @@ -70,6 +72,26 @@ def status_codes(request): } +def inventree_settings(request): + """ + Adds two context objects to the request: + + user_settings - A key:value dict of all user InvenTree settings for the current user + global_settings - A key:value dict of all global InvenTree settings + + Providing a single context object for all settings should reduce the number of db hits + """ + + ctx = {} + + if request.user: + ctx["user_settings"] = common.models.InvenTreeUserSetting.allValues(user=request.user) + + ctx["global_settings"] = common.models.InvenTreeSetting.allValues() + + return ctx + + def user_roles(request): """ Return a map of the current roles assigned to the user. diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 4543b873bd..1ea4815f65 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -320,9 +320,11 @@ TEMPLATES = [ 'django.template.context_processors.i18n', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + # Custom InvenTree context processors 'InvenTree.context.health_status', 'InvenTree.context.status_codes', 'InvenTree.context.user_roles', + 'InvenTree.context.inventree_settings', ], }, }, diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 3924a516f3..d7152ac6ef 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -49,55 +49,37 @@ class BaseInvenTreeSetting(models.Model): are assigned their default values """ - keys = set() - settings = [] - results = cls.objects.all() if user is not None: results = results.filter(user=user) # Query the database + settings = {} + for setting in results: if setting.key: - settings.append({ - "key": setting.key.upper(), - "value": setting.value - }) - - keys.add(setting.key.upper()) + settings[setting.key.upper()] = setting.value # Specify any "default" values which are not in the database for key in cls.GLOBAL_SETTINGS.keys(): - if key.upper() not in keys: + if key.upper() not in settings: - settings.append({ - "key": key.upper(), - "value": cls.get_setting_default(key) - }) - - # Enforce javascript formatting - for idx, setting in enumerate(settings): - - key = setting['key'] - value = setting['value'] + settings[key.upper()] = cls.get_setting_default(key) + for key, value in settings.items(): validator = cls.get_setting_validator(key) - # Convert to javascript compatible booleans if cls.validator_is_bool(validator): - value = str(value).lower() - - # Numerical values remain the same + value = InvenTree.helpers.str2bool(value) elif cls.validator_is_int(validator): - pass + try: + value = int(value) + except ValueError: + value = cls.get_setting_default(key) - # Wrap strings with quotes - else: - value = format_html("'{}'", value) - - setting["value"] = value + settings[key] = value return settings diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index b12a59f136..054cd0be95 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -6,6 +6,7 @@ over and above the built-in Django tags. import os import sys +from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ from django.conf import settings as djangosettings @@ -208,24 +209,6 @@ def settings_value(key, *args, **kwargs): return InvenTreeSetting.get_setting(key) -@register.simple_tag() -def user_settings(user, *args, **kwargs): - """ - Return all USER settings as a key:value dict - """ - - return InvenTreeUserSetting.allValues(user=user) - - -@register.simple_tag() -def global_settings(*args, **kwargs): - """ - Return all GLOBAL InvenTree settings as a key:value dict - """ - - return InvenTreeSetting.allValues() - - @register.simple_tag() def get_color_theme_css(username): try: @@ -262,6 +245,25 @@ def get_available_themes(*args, **kwargs): return themes +@register.simple_tag() +def primitive_to_javascript(primitive): + """ + Convert a python primitive to a javascript primitive. + + e.g. True -> true + 'hello' -> '"hello"' + """ + + if type(primitive) is bool: + return str(primitive).lower() + + elif type(primitive) in [int, float]: + return primitive + + else: + # Wrap with quotes + return format_html("'{}'", primitive) + @register.filter def keyvalue(dict, key): """ diff --git a/InvenTree/templates/js/dynamic/settings.js b/InvenTree/templates/js/dynamic/settings.js index ad4e297c4a..3f96e9d988 100644 --- a/InvenTree/templates/js/dynamic/settings.js +++ b/InvenTree/templates/js/dynamic/settings.js @@ -1,17 +1,14 @@ {% load inventree_extras %} // InvenTree settings -{% user_settings request.user as USER_SETTINGS %} -{% global_settings as GLOBAL_SETTINGS %} - var user_settings = { - {% for setting in USER_SETTINGS %} - {{ setting.key }}: {{ setting.value }}, + {% for key, value in user_settings.items %} + {{ key }}: {% primitive_to_javascript value %}, {% endfor %} }; var global_settings = { - {% for setting in GLOBAL_SETTINGS %} - {{ setting.key }}: {{ setting.value }}, + {% for key, value in global_settings.items %} + {{ key }}: {% primitive_to_javascript value %}, {% endfor %} }; \ No newline at end of file From cef09acd543e5f3fc637d4648f6955dddea3d465 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 15 Aug 2021 12:05:53 +1000 Subject: [PATCH 2/3] Partial reversion of some stuff --- InvenTree/InvenTree/context.py | 20 ------------------- InvenTree/InvenTree/settings.py | 1 - .../part/templatetags/inventree_extras.py | 18 +++++++++++++++++ InvenTree/templates/js/dynamic/settings.js | 8 ++++++-- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/InvenTree/InvenTree/context.py b/InvenTree/InvenTree/context.py index 6f59840967..85a320afb4 100644 --- a/InvenTree/InvenTree/context.py +++ b/InvenTree/InvenTree/context.py @@ -72,26 +72,6 @@ def status_codes(request): } -def inventree_settings(request): - """ - Adds two context objects to the request: - - user_settings - A key:value dict of all user InvenTree settings for the current user - global_settings - A key:value dict of all global InvenTree settings - - Providing a single context object for all settings should reduce the number of db hits - """ - - ctx = {} - - if request.user: - ctx["user_settings"] = common.models.InvenTreeUserSetting.allValues(user=request.user) - - ctx["global_settings"] = common.models.InvenTreeSetting.allValues() - - return ctx - - def user_roles(request): """ Return a map of the current roles assigned to the user. diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index 1ea4815f65..96b7da140d 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -324,7 +324,6 @@ TEMPLATES = [ 'InvenTree.context.health_status', 'InvenTree.context.status_codes', 'InvenTree.context.user_roles', - 'InvenTree.context.inventree_settings', ], }, }, diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index 054cd0be95..f36746e7a2 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -209,6 +209,24 @@ def settings_value(key, *args, **kwargs): return InvenTreeSetting.get_setting(key) +@register.simple_tag() +def user_settings(user, *args, **kwargs): + """ + Return all USER settings as a key:value dict + """ + + return InvenTreeUserSetting.allValues(user=user) + + +@register.simple_tag() +def global_settings(*args, **kwargs): + """ + Return all GLOBAL InvenTree settings as a key:value dict + """ + + return InvenTreeSetting.allValues() + + @register.simple_tag() def get_color_theme_css(username): try: diff --git a/InvenTree/templates/js/dynamic/settings.js b/InvenTree/templates/js/dynamic/settings.js index 3f96e9d988..60172ead64 100644 --- a/InvenTree/templates/js/dynamic/settings.js +++ b/InvenTree/templates/js/dynamic/settings.js @@ -1,14 +1,18 @@ {% load inventree_extras %} // InvenTree settings +{% user_settings request.user as USER_SETTINGS %} + var user_settings = { - {% for key, value in user_settings.items %} + {% for key, value in USER_SETTINGS.items %} {{ key }}: {% primitive_to_javascript value %}, {% endfor %} }; +{% global_settings as GLOBAL_SETTINGS %} + var global_settings = { - {% for key, value in global_settings.items %} + {% for key, value in GLOBAL_SETTINGS.items %} {{ key }}: {% primitive_to_javascript value %}, {% endfor %} }; \ No newline at end of file From 8861ffad81512626cc327cc68bd7a25a9ff001ed Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 15 Aug 2021 12:06:31 +1000 Subject: [PATCH 3/3] PEP fixes --- InvenTree/InvenTree/context.py | 2 -- InvenTree/common/models.py | 1 - InvenTree/part/templatetags/inventree_extras.py | 1 + 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/InvenTree/InvenTree/context.py b/InvenTree/InvenTree/context.py index 85a320afb4..3e1f98ffc2 100644 --- a/InvenTree/InvenTree/context.py +++ b/InvenTree/InvenTree/context.py @@ -10,8 +10,6 @@ from InvenTree.status_codes import StockHistoryCode import InvenTree.status -import common.models - from users.models import RuleSet diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index d7152ac6ef..cf5e44595a 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -20,7 +20,6 @@ from djmoney.contrib.exchange.models import convert_money from djmoney.contrib.exchange.exceptions import MissingRate from django.utils.translation import ugettext_lazy as _ -from django.utils.html import format_html from django.core.validators import MinValueValidator, URLValidator from django.core.exceptions import ValidationError diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index f36746e7a2..3b88deb504 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -282,6 +282,7 @@ def primitive_to_javascript(primitive): # Wrap with quotes return format_html("'{}'", primitive) + @register.filter def keyvalue(dict, key): """