Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
django-检测不带“的完整性错误”;保存();_Django - Fatal编程技术网

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()
来防止无限循环-您不需要再次调用model
save()
方法。这就是说,除非你正在建造一个非常高容量的网站,添加一个阅读不是一个巨大的开销。说,存储蛞蝓是一个需要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