【问题标题】:Django unique_together not preventing duplicatesDjango unique_together 不防止重复
【发布时间】:2012-01-13 00:16:55
【问题描述】:

我显然不明白如何正确地做到这一点,有人可以让我直截了当。这是模型:

class Team(models.Model):
   teamID=models.CharField(max_length=255) #this will be generated on the iPad
   name=models.CharField(max_length=255)
   slug=models.SlugField(max_length=50) 
   teamNumber=models.CharField(max_length=30)
   checkIn=models.DateTimeField(default=datetime.now())
   totalScore=models.IntegerField(max_length=6) 

   class Meta:
       unique_together = ("teamID", "name", "slug", "teamNumber", "totalScore")

如果我连续提交两次,它会保存所有内容。哎呀!!!

【问题讨论】:

  • 还有一个模型把这个模型当作FK,不知道跟这个有关系吗?
  • 这是在数据库级别强制执行的 - 您是否记得在添加 unique_together 字段后运行 python manage.py syncdb
  • 好吧,我进行了迁移...让我尝试一个简单的“ol同步”
  • 嗯,值得一试。你用的是什么版本的 Django?
  • 如果您再次运行syncdb也没关系,这不会更新数据库架构。使用 south 进行迁移,或者删除并重新创建表。

标签: python django


【解决方案1】:

正如 aganders3 提到的,约束是在数据库级别强制执行的;我假设您使用的数据库如 SQLite 不支持这种约束。

它通过管理员按预期工作的原因是它自己进行唯一性检查(它不严格依赖数据库来表示违反约束)。

您可以切换到支持这种唯一性约束的数据库引擎(MySQL 或 Postgres 都可以),或者您可以考虑使用信号添加检查:http://djangosnippets.org/snippets/1628/

【讨论】:

    【解决方案2】:

    尝试正确的嵌套元组语法((foo,bar),) 而不是(foo, bar)

    https://docs.djangoproject.com/en/dev/ref/models/options/#unique-together

    【讨论】:

    • 我有...无济于事,我一定只是在这里遗漏了一些简单的东西
    • 好的,这就是问题所在,如果我在管理员 Django 中输入数据 防止重复条目,但是发送我的 Django 应用程序数据的奇怪的小移动应用程序不能像 Django admin 一样进行任何验证,也不能从我的 Django 应用程序接收消息。我只需要 Django 根本不写这些数据。我知道,这是一个奇怪的用例。
    • 好的,所以现在我决定返回应用程序并发送验证错误消息。我认为这现在会起作用。很抱歉误报。
    • 其实不需要嵌套元组语法。也许是当时?
    • Idk @mlissner 但在 django 2.2 中,我刚刚解决了这个问题......说我想知道为什么它现在开始,单元组过去一直工作到这个新模型
    【解决方案3】:

    是的,参数 unique_together 接收一个元组作为输入,我没有测试超过两个元素的元组,但它应该可以工作

    你的例子:

    unique_together = (("teamID", "name"), ("slug", "teamNumber"))
    

    或:

    unique_together = (("teamID", "name", "slug", "teamNumber", "totalScore"))
    

    【讨论】:

    • 您的第二个示例缺少 1 元素元组中所需的尾随逗号,从而有效地使其成为长度为 4 且带有额外无操作括号的元组。它有效,但它确实 b/c 如果只有 1 个唯一分组,Django 不需要元组的元组。我的问题得到解决,确保 unique_together 在 Meta 类下,而不是模型下。哦!
    【解决方案4】:

    我发现这种方法很有帮助,无需添加任何不必要的字段

    class Request(models.Model):
        user = models.ForeignKey(User, related_name='request_list', on_delete=models.CASCADE)
        requested_user = models.ForeignKey(User, on_delete=models.CASCADE)
        request_date = models.DateField(default=timezone.now())
        request_status = models.BooleanField(default=False)
    
        def save(self, *args, **kwargs):
            # Checking for duplicate requests
            try:
                request = Request.objects.get(user=self.user, requested_user=self.requested_user)
                raise ValidationError('Duplicate Value', code='invalid')
            except self.DoesNotExist:
                super().save(*args, **kwargs)
    
            # Checking for reversed duplicate requests
            try:
                request_new = Request.objects.get(requested_user=self.user, user=self.requested_user)
                raise ValidationError('Duplicate Value', code='invalid')
            except self.DoesNotExist:
                super().save(*args, **kwargs)
    
        def __str__(self):
            return self.user.username + '------>' + self.requested_user.username
    

    【讨论】:

    • 为什么这么麻烦,而 unique_together 做到了这一切?
    猜你喜欢
    • 2011-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 2012-08-13
    • 2019-08-15
    相关资源
    最近更新 更多