django-检测不带“的完整性错误”;保存();
好的,我需要一点帮助 我有一个模型,它有一个名为django-检测不带“的完整性错误”;保存();,django,Django,好的,我需要一点帮助 我有一个模型,它有一个名为slug=models.SlugField(unique=True)的字段,如果slug已经存在,我试图通过向slug添加1来将此字段设置为save(),以此类推 我想考虑一下赛跑情况。 def set_uniqslug(self, slug, i=0): new_slug = u"{}{}".format(slug, str(i) if i else '') try: with transaction.atomic
slug=models.SlugField(unique=True)
的字段,如果slug已经存在,我试图通过向slug添加1
来将此字段设置为save()
,以此类推
我想考虑一下赛跑情况。
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)
它正在工作,但我胃痛,因为我锁着
读-动作。我这样做是不是阻止了其他的查询或者做了其他不好的事情 您的检查和设置版本可能无法工作。这将取决于您的数据库及其事务隔离级别的实现;但以PostgreSQL为例,默认的readcommitted
隔离级别不会阻止另一个事务在检查和设置之间插入具有相同slug的行
因此,请使用您最初的、乐观的锁定想法。正如雨果·罗杰·布朗所指出的,通过调用超类的save()
,可以避免无限循环
最后,你可能想考虑另一种蛞蝓格式。很多时候,slug将包含数据库id(实际上与StackOverflow本身类似),这消除了重复slug的可能性。您可以通过调用set\u uniqslug()
方法中的super().save()
来防止无限循环-您不需要再次调用modelsave()
方法。这就是说,除非你正在建造一个非常高容量的网站,添加一个阅读不是一个巨大的开销。说,存储蛞蝓是一个需要Google的问题,建议一个更简单的蛞蝓可能值得考虑。考虑一个代码>名称PK < /COD>蛞蝓格式,解决段塞冲突的一种更简单的方法。@abstractpaper非常好的观点:)@doniyor如果你不想公开你的id,你也可以做类似于pk^0x109ABE7
的事情。你是对的,但我想在url中隐藏id,这样就没有人知道db中有多少公司配置文件了。。。但我认为,这是更好更安全的方式。。
with transaction.atomic():
if Company.objects.filter(slug=new_slug).exists():
i += 1
return self.set_uniqslug(slug, i)
return new_slug