diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py
index 288e3451ad..ad144cd8db 100644
--- a/InvenTree/common/models.py
+++ b/InvenTree/common/models.py
@@ -79,7 +79,7 @@ class BaseInvenTreeSetting(models.Model):
self.key = str(self.key).upper()
self.clean(**kwargs)
- self.validate_unique()
+ self.validate_unique(**kwargs)
super().save()
@@ -230,10 +230,6 @@ class BaseInvenTreeSetting(models.Model):
return choices
- @classmethod
- def get_filters(cls, key, **kwargs):
- return {'key__iexact': key}
-
@classmethod
def get_setting_object(cls, key, **kwargs):
"""
@@ -247,29 +243,35 @@ class BaseInvenTreeSetting(models.Model):
settings = cls.objects.all()
+ filters = {
+ 'key__iexact': key,
+ }
+
# Filter by user
user = kwargs.get('user', None)
if user is not None:
- settings = settings.filter(user=user)
+ filters['user'] = user
- try:
- setting = settings.filter(**cls.get_filters(key, **kwargs)).first()
- except (ValueError, cls.DoesNotExist):
- setting = None
- except (IntegrityError, OperationalError):
- setting = None
+ # Filter by plugin
+ plugin = kwargs.get('plugin', None)
- plugin = kwargs.pop('plugin', None)
-
- if plugin:
+ if plugin is not None:
from plugin import InvenTreePluginBase
if issubclass(plugin.__class__, InvenTreePluginBase):
plugin = plugin.plugin_config()
+ filters['plugin'] = plugin
kwargs['plugin'] = plugin
+ try:
+ setting = settings.filter(**filters).first()
+ except (ValueError, cls.DoesNotExist):
+ setting = None
+ except (IntegrityError, OperationalError):
+ setting = None
+
# Setting does not exist! (Try to create it)
if not setting:
@@ -287,7 +289,7 @@ class BaseInvenTreeSetting(models.Model):
try:
# Wrap this statement in "atomic", so it can be rolled back if it fails
with transaction.atomic():
- setting.save()
+ setting.save(**kwargs)
except (IntegrityError, OperationalError):
# It might be the case that the database isn't created yet
pass
@@ -342,8 +344,26 @@ class BaseInvenTreeSetting(models.Model):
if change_user is not None and not change_user.is_staff:
return
+ filters = {
+ 'key__iexact': key,
+ }
+
+ user = kwargs.get('user', None)
+ plugin = kwargs.get('plugin', None)
+
+ if user is not None:
+ filters['user'] = user
+
+ if plugin is not None:
+ from plugin import InvenTreePluginBase
+
+ if issubclass(plugin.__class__, InvenTreePluginBase):
+ filters['plugin'] = plugin.plugin_config()
+ else:
+ filters['plugin'] = plugin
+
try:
- setting = cls.objects.get(**cls.get_filters(key, **kwargs))
+ setting = cls.objects.get(**filters)
except cls.DoesNotExist:
if create:
@@ -438,17 +458,37 @@ class BaseInvenTreeSetting(models.Model):
validator(self.value)
def validate_unique(self, exclude=None, **kwargs):
- """ Ensure that the key:value pair is unique.
+ """
+ Ensure that the key:value pair is unique.
In addition to the base validators, this ensures that the 'key'
is unique, using a case-insensitive comparison.
+
+ Note that sub-classes (UserSetting, PluginSetting) use other filters
+ to determine if the setting is 'unique' or not
"""
super().validate_unique(exclude)
+ filters = {
+ 'key__iexact': self.key,
+ }
+
+ user = getattr(self, 'user', None)
+ plugin = getattr(self, 'plugin', None)
+
+ if user is not None:
+ filters['user'] = user
+
+ if plugin is not None:
+ filters['plugin'] = plugin
+
try:
- setting = self.__class__.objects.exclude(id=self.id).filter(**self.get_filters(self.key, **kwargs))
+ # Check if a duplicate setting already exists
+ setting = self.__class__.objects.filter(**filters).exclude(id=self.id)
+
if setting.exists():
raise ValidationError({'key': _('Key string must be unique')})
+
except self.DoesNotExist:
pass
@@ -1312,16 +1352,9 @@ class InvenTreeUserSetting(BaseInvenTreeSetting):
def get_setting_object(cls, key, user):
return super().get_setting_object(key, user=user)
- def validate_unique(self, exclude=None):
+ def validate_unique(self, exclude=None, **kwargs):
return super().validate_unique(exclude=exclude, user=self.user)
- @classmethod
- def get_filters(cls, key, **kwargs):
- return {
- 'key__iexact': key,
- 'user__id': kwargs['user'].id
- }
-
def to_native_value(self):
"""
Return the "pythonic" value,
diff --git a/InvenTree/plugin/models.py b/InvenTree/plugin/models.py
index e33d452e0a..44eeafd012 100644
--- a/InvenTree/plugin/models.py
+++ b/InvenTree/plugin/models.py
@@ -175,23 +175,6 @@ class PluginSetting(common.models.BaseInvenTreeSetting):
return super().get_setting_definition(key, **kwargs)
- @classmethod
- def get_filters(cls, key, **kwargs):
- """
- Override filters method to ensure settings are filtered by plugin id
- """
-
- filters = super().get_filters(key, **kwargs)
-
- plugin = kwargs.get('plugin', None)
-
- if plugin:
- if issubclass(plugin.__class__, InvenTreePluginBase):
- plugin = plugin.plugin_config()
- filters['plugin'] = plugin
-
- return filters
-
plugin = models.ForeignKey(
PluginConfig,
related_name='settings',
diff --git a/InvenTree/templates/js/translated/label.js b/InvenTree/templates/js/translated/label.js
index 5215ce9d28..c0f4c2f735 100644
--- a/InvenTree/templates/js/translated/label.js
+++ b/InvenTree/templates/js/translated/label.js
@@ -263,7 +263,7 @@ function selectLabel(labels, items, options={}) {
`;
plugins.forEach(function(plugin) {
- plugin_selection += ``;
+ plugin_selection += ``;
});
plugin_selection += `