From 3e33326120781d78929b8a86808a705ff1e02e1a Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sun, 15 Sep 2019 22:46:24 +1000 Subject: [PATCH] Add the InvenTreeSetting model - Storage of singleton settings in key:value pairs --- .../migrations/0004_inventreesetting.py | 21 ++++++ InvenTree/common/models.py | 71 +++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 InvenTree/common/migrations/0004_inventreesetting.py diff --git a/InvenTree/common/migrations/0004_inventreesetting.py b/InvenTree/common/migrations/0004_inventreesetting.py new file mode 100644 index 0000000000..64fc9cd486 --- /dev/null +++ b/InvenTree/common/migrations/0004_inventreesetting.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.5 on 2019-09-15 12:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('common', '0003_auto_20190902_2310'), + ] + + operations = [ + migrations.CreateModel( + name='InvenTreeSetting', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('key', models.CharField(help_text='Settings key', max_length=50, unique=True)), + ('value', models.CharField(blank=True, help_text='Settings value', max_length=200)), + ], + ), + ] diff --git a/InvenTree/common/models.py b/InvenTree/common/models.py index 61bb9ec138..a5bc537325 100644 --- a/InvenTree/common/models.py +++ b/InvenTree/common/models.py @@ -9,6 +9,77 @@ from __future__ import unicode_literals from django.db import models from django.utils.translation import ugettext as _ from django.core.validators import MinValueValidator, MaxValueValidator +from django.core.exceptions import ValidationError + + +class InvenTreeSetting(models.Model): + """ + An InvenTreeSetting object is a key:value pair used for storing + single values (e.g. one-off settings values). + + The class provides a way of retrieving the value for a particular key, + even if that key does not exist. + """ + + @classmethod + def get_setting(cls, key, backup_value=None): + """ + Get the value of a particular setting. + If it does not exist, return the backup value (default = None) + """ + + try: + setting = InvenTreeSetting.objects.get(key__iexact=key) + return setting.value + except InvenTreeSetting.DoesNotExist: + return backup_value + + @classmethod + def set_setting(cls, key, value, user, create=True): + """ + Set the value of a particular setting. + If it does not exist, option to create it. + + Args: + key: settings key + value: New value + user: User object (must be staff member to update a core setting) + create: If True, create a new setting if the specified key does not exist + """ + + if not user.is_staff: + return + + try: + setting = InvenTreeSetting.objects.get(key__iexact=key) + except InvenTreeSetting.DoesNotExist: + + if create: + setting = InvenTreeSetting(key=key) + else: + return + + setting.value = value + setting.save() + + key = models.CharField(max_length=50, blank=False, unique=True, help_text=_('Settings key')) + + value = models.CharField(max_length=200, blank=True, unique=False, help_text=_('Settings value')) + + def validate_unique(self, exclude=None): + """ 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. + """ + + super().validate_unique(exclude) + + try: + setting = InvenTreeSetting.objects.exclude(id=self.id).filter(key__iexact=self.key) + if setting.exists(): + raise ValidationError({'key': _('Key string must be unique')}) + except InvenTreeSetting.DoesNotExist: + pass class Currency(models.Model):