From 28c72e01b9555d64f732571cba9ed7bafd97b9e6 Mon Sep 17 00:00:00 2001 From: caoqianming Date: Mon, 30 Dec 2024 10:24:12 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20base=20=E4=BC=98=E5=8C=96safe=5Fget=5Fo?= =?UTF-8?q?r=5Fcreate=E4=BB=A5=E5=A4=84=E7=90=86=E5=B9=B6=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/utils/models.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/apps/utils/models.py b/apps/utils/models.py index b9ff20cb..7d9b6b47 100755 --- a/apps/utils/models.py +++ b/apps/utils/models.py @@ -112,15 +112,21 @@ class BaseModel(models.Model): abstract = True @classmethod - def safe_get_or_create(cls, **kwargs): - defaults = kwargs.pop('defaults', {}) - for attempt in range(5): + def safe_get_or_create(cls, defaults=None, **kwargs): + defaults = defaults or {} + + with transaction.atomic(): try: - return cls.objects.get_or_create(defaults=defaults, **kwargs) - except IntegrityError: - if attempt < 4: - time.sleep(0.1) - else: + ins = cls.objects.select_for_update().get(**kwargs) + return ins, False + except cls.DoesNotExist: + try: + ins = cls.objects.create(**defaults, **kwargs) + except IntegrityError: + try: + return cls.objects.get(**kwargs), False + except cls.DoesNotExist: + pass raise def handle_parent(self):