Merge pull request #2771 from SchrodingersGat/plugin-settings-fix

Ensure that kwargs are correctly passed through the settings chain
This commit is contained in:
Oliver 2022-03-25 14:53:22 +11:00 committed by GitHub
commit 5921964fdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 45 deletions

View File

@ -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,

View File

@ -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',

View File

@ -263,7 +263,7 @@ function selectLabel(labels, items, options={}) {
`;
plugins.forEach(function(plugin) {
plugin_selection += `<option value='${plugin.key}' title='${plugin.meta.human_name}'>${plugin.meta.description} - <small>${plugin.meta.human_name}</small></option>`;
plugin_selection += `<option value='${plugin.key}' title='${plugin.meta.human_name}'>${plugin.name} - <small>${plugin.meta.human_name}</small></option>`;
});
plugin_selection += `