From 4d9e92011e1fc3844d202ca10ec3c40af6df31f8 Mon Sep 17 00:00:00 2001 From: Lukas <76838159+wolflu05@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:53:06 +0200 Subject: [PATCH] Fix/settings bugs and added model SettingKeyType typing (#4944) * fix .gitignore and spelling issues * Fix setting get not cached correctly * Add model to settings key type * Fix plugin setting slug url * Fix typo * Fix resetting of related setting field * Improved model comment --- .gitignore | 2 +- InvenTree/common/models.py | 16 +++++++++++----- InvenTree/part/templatetags/inventree_extras.py | 2 +- InvenTree/plugin/api.py | 6 +++--- InvenTree/templates/js/dynamic/settings.js | 9 +++++++-- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 0a9726edaa..38dea68006 100644 --- a/.gitignore +++ b/.gitignore @@ -97,7 +97,7 @@ node_modules/ maintenance_mode_state.txt # plugin dev directory -./plugins/ +InvenTree/plugins/ # Compiled translation files *.mo diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index d010ecf34c..4c31a670e2 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -127,6 +127,7 @@ class SettingsKeyType(TypedDict, total=False): before_save: Function that gets called after save with *args, **kwargs (optional) after_save: Function that gets called after save with *args, **kwargs (optional) protected: Protected values are not returned to the client, instead "***" is returned (optional, default: False) + model: Auto create a dropdown menu to select an associated model instance (e.g. 'company.company', 'auth.user' and 'auth.group' are possible too, optional) """ name: str @@ -139,6 +140,7 @@ class SettingsKeyType(TypedDict, total=False): before_save: Callable[..., None] after_save: Callable[..., None] protected: bool + model: str class BaseInvenTreeSetting(models.Model): @@ -170,12 +172,12 @@ class BaseInvenTreeSetting(models.Model): # Execute before_save action self._call_settings_function('before_save', args, kwargs) - # Update this setting in the cache + super().save() + + # Update this setting in the cache after it was saved so a pk exists if do_cache: self.save_to_cache() - super().save() - # Execute after_save action self._call_settings_function('after_save', args, kwargs) @@ -205,6 +207,10 @@ class BaseInvenTreeSetting(models.Model): ckey = self.cache_key + # skip saving to cache if no pk is set + if self.pk is None: + return + logger.debug(f"Saving setting '{ckey}' to cache") try: @@ -254,7 +260,7 @@ class BaseInvenTreeSetting(models.Model): results = cls.objects.all() if exclude_hidden: - # Keys which start with an undersore are used for internal functionality + # Keys which start with an underscore are used for internal functionality results = results.exclude(key__startswith='_') # Optionally filter by other keys @@ -469,7 +475,7 @@ class BaseInvenTreeSetting(models.Model): If it does not exist, return the backup value (default = None) """ - # If no backup value is specified, atttempt to retrieve a "default" value + # If no backup value is specified, attempt to retrieve a "default" value if backup_value is None: backup_value = cls.get_setting_default(key, **kwargs) diff --git a/InvenTree/part/templatetags/inventree_extras.py b/InvenTree/part/templatetags/inventree_extras.py index ab4255c9fe..8562f1e522 100644 --- a/InvenTree/part/templatetags/inventree_extras.py +++ b/InvenTree/part/templatetags/inventree_extras.py @@ -315,7 +315,7 @@ def default_currency(*args, **kwargs): @register.simple_tag() def setting_object(key, *args, **kwargs): - """Return a setting object speciifed by the given key. + """Return a setting object specified by the given key. (Or return None if the setting does not exist) if a user-setting was requested return that diff --git a/InvenTree/plugin/api.py b/InvenTree/plugin/api.py index 4246fe21d5..4947df66e1 100644 --- a/InvenTree/plugin/api.py +++ b/InvenTree/plugin/api.py @@ -164,7 +164,7 @@ class PluginSettingList(ListAPI): def check_plugin(plugin_slug: str, plugin_pk: int) -> InvenTreePlugin: - """Check that a plugin for the provided slug exsists and get the config. + """Check that a plugin for the provided slug exists and get the config. Args: plugin_slug (str): Slug for plugin. @@ -247,7 +247,7 @@ plugin_api_urls = [ re_path(r'^plugins/', include([ # Plugin settings URLs re_path(r'^settings/', include([ - re_path(r'^(?P\w+)/(?P\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), # Used for admin interface + re_path(r'^(?P[-\w]+)/(?P\w+)/', PluginSettingDetail.as_view(), name='api-plugin-setting-detail'), # Used for admin interface re_path(r'^.*$', PluginSettingList.as_view(), name='api-plugin-setting-list'), ])), @@ -258,7 +258,7 @@ plugin_api_urls = [ re_path(r'^.*$', PluginDetail.as_view(), name='api-plugin-detail'), ])), - # Plugin managment + # Plugin management re_path(r'^install/', PluginInstall.as_view(), name='api-plugin-install'), re_path(r'^activate/', PluginActivate.as_view(), name='api-plugin-activate'), diff --git a/InvenTree/templates/js/dynamic/settings.js b/InvenTree/templates/js/dynamic/settings.js index 9dac2a3371..56984189fe 100644 --- a/InvenTree/templates/js/dynamic/settings.js +++ b/InvenTree/templates/js/dynamic/settings.js @@ -111,8 +111,13 @@ function editSetting(key, options={}) { return data; }, processBeforeUpload: function(data) { - // Convert value to string - data.value = data.value.toString(); + if(response.type === 'related field' && data.value === null) { + // related fields throw an error because they are set to null on delete + data.value = ""; + } else { + // Convert value to string + data.value = data.value.toString(); + } return data; },