oncall-engine/engine/apps/base/models/dynamic_setting.py
Michael Derynck 6b40f95033 World, meet OnCall!
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>
2022-06-03 08:09:47 -06:00

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