Co-authored-by: Eve832 <eve.meelan@grafana.com>
Co-authored-by: Francisco Montes de Oca <nevermind89x@gmail.com>
Co-authored-by: Ildar Iskhakov <ildar.iskhakov@grafana.com>
Co-authored-by: Innokentii Konstantinov <innokenty.konstantinov@grafana.com>
Co-authored-by: Julia <ferril.darkdiver@gmail.com>
Co-authored-by: maskin25 <kengurek@gmail.com>
Co-authored-by: Matias Bordese <mbordese@gmail.com>
Co-authored-by: Matvey Kukuy <motakuk@gmail.com>
Co-authored-by: Michael Derynck <michael.derynck@grafana.com>
Co-authored-by: Richard Hartmann <richih@richih.org>
Co-authored-by: Robby Milo <robbymilo@fastmail.com>
Co-authored-by: Timur Olzhabayev <timur.olzhabayev@grafana.com>
Co-authored-by: Vadim Stepanov <vadimkerr@gmail.com>
Co-authored-by: Yulia Shanyrova <yulia.shanyrova@grafana.com>
39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
from django.db import IntegrityError, models
|
|
from django.db.models import JSONField
|
|
|
|
|
|
class DynamicSettingsManager(models.Manager):
|
|
def get_or_create(self, defaults=None, **kwargs):
|
|
"""
|
|
Using get_or_create inside celery task sometimes triggers making two identical DynamicSettings.
|
|
E.g. https://gitlab.amixr.io/amixr/amixr/issues/843
|
|
More info: https://stackoverflow.com/questions/17960593/multipleobjectsreturned-with-get-or-create
|
|
Solution is to create UniqueConstraint on DynamicSetting.Name and catch IntegrityError.
|
|
Django 3 has built-in check https://github.com/django/django/blob/master/django/db/models/query.py#L571
|
|
As for now we are using Django 2.2 which has not.
|
|
# TODO: remove this method when we will move to Django 3
|
|
So it is overridden get_or_create to catch IntegrityError and just return object in this case.
|
|
"""
|
|
try:
|
|
return super(DynamicSettingsManager, self).get_or_create(defaults=defaults, **kwargs)
|
|
except IntegrityError:
|
|
try:
|
|
return self.get(**kwargs), False
|
|
except self.model.DoesNotExist:
|
|
pass
|
|
raise
|
|
|
|
|
|
class DynamicSetting(models.Model):
|
|
objects = DynamicSettingsManager()
|
|
|
|
name = models.CharField(max_length=100)
|
|
boolean_value = models.BooleanField(null=True, default=None)
|
|
numeric_value = models.IntegerField(null=True, default=None)
|
|
json_value = JSONField(default=None, null=True, blank=True)
|
|
|
|
class Meta:
|
|
constraints = [models.UniqueConstraint(fields=["name"], name="unique_dynamic_setting_name")]
|
|
|
|
def __str__(self):
|
|
return self.name
|