Хорошо, мне нужна небольшая помощь здесь.django - обнаружить IntegrityError без "save()"
У меня есть модель, которая имеет поле под названием slug = models.SlugField(unique=True)
, и я пытаюсь установить это поле на save()
путем добавления 1
пули, если пробка уже существует и так далее.
Я хочу рассмотреть условия гонки.
def set_uniqslug(self, slug, i=0):
new_slug = u"{}{}".format(slug, str(i) if i else '')
try:
with transaction.atomic():
self.slug = slugify(new_slug.lower())
self.save()
return self
return self
except IntegrityError as e:
i += 1
return set_uniqslug(self, slug, i)
def save(self, *args, **kwargs):
if not self.pk:
set_uniqslug(self.name.lower()) # <--- but it does "save" above.
# i want something like:
# self.slug = self.get_uniqslug(self.name.lower())
super(Company, self).save(*args, **kwargs)
моя проблема, если я называю set_uniqslug()
, он должен попытаться спасти, просто знать, если есть IntegrityError. в моем коде он переходит в бесконечный цикл.
Как я могу узнать без сохранения, если есть IntegrityError, а затем просто вернуть уникальный slug обратно в метод save()
?
обновление:
я попытался это:
with transaction.atomic():
if Company.objects.filter(slug=new_slug).exists():
i += 1
return self.set_uniqslug(slug, i)
return new_slug
он работает, но у меня есть боли в животе, заблокировав READ
-действие. я не блокирую другие запросы или делаю другие плохие вещи, делая это?
Вы можете предотвратить бесконечный цикл, вызвав 'super(). Save()' внутри метода set_uniqslug() ', вам больше не нужно вызывать метод' save() '. Тем не менее, если вы не строите сайт с очень высоким объемом, добавление чтения не является огромным издержками. –
Тем не менее, тот факт, что хранение пули является проблемой, которая требует поиска в Google, предполагает, что более простой слизень стоит рассмотреть. –
Рассмотрите формат «name-pk» slug, более простой способ разрешить конфликты slug. – abstractpaper