【问题标题】:Django conditional unique togetherDjango条件唯一一起
【发布时间】:2012-01-04 22:28:21
【问题描述】:

我的模型如下所示:

class LibraryEntry(models.Model):
  host_lib_song_id = models.IntegerField()
  song = models.CharField(max_length=200)
  artist = models.CharField(max_length=200)
  album = models.CharField(max_length=200)
  owning_user = models.ForeignKey(User)
  is_deleted = models.BooleanField(default=False)

现在,如果我选择 is_deleted=False 的位置,host_lib_song_idowning_user 的组合应该是唯一的。我该如何表达?

【问题讨论】:

标签: python django model


【解决方案1】:

您不能通过Meta.unique_together 约束来表达这一点,而是通过django's model validation

class LibraryEntry(models.Model):
    def clean(self):
        from django.core.exceptions import ValidationError
        try:
            # try to find a duplicate entry and exclude 'self'
            duplicate = LibraryEntry.objects.exclude(pk=self.pk)\
                .get(owning_user=self.owning_user, 
                     host_lib_song_id=self.host_lib_song_id,
                     is_deleted=False)
            raise ValidationError('Library Entry already exists!')
        except: LibraryEntry.DoesNotExist:
            # no duplicate found
            pass

【讨论】:

  • 这不是在数据库级别强制执行的
【解决方案2】:

如果is_deletedFalse 更合适,则覆盖validate_unique 以检查唯一性:

...

def validate_unique(self, exclude=None):
    if not self.is_deleted and \
       LibraryEntry.objects.exclude(pk=self.pk).filter(host_lib_song_id=self.host_lib_song_id, owning_user=self.owning_user).exists():
        raise ValidationError('Some error message about uniqueness required')
    super(LibraryEntry, self).validate_unique(exclude=exclude)

【讨论】:

  • PageSection 是怎么回事?那是错字吗?另外,我想我想要if self.is_deleted,因为我只想对没有删除的内容强制执行此操作。对吗?
  • 两个帐户都正确。从我正在处理的项目中复制它并没有抓住一切。答案已更新。
  • 唯一性不是一起生成数据库约束吗?覆盖 validate_unique 将阻止 Django 运行唯一性检查,但是当您尝试保存到 db 时会出现完整性错误。
  • @Alasdair:你是对的。我忘了它是在数据库级别强制执行的。覆盖validate_unique 仍然是合适的方法,但您需要自己进行验证,而不是使用约束。上面更新了代码。
【解决方案3】:

如果您使用的是 Django 2.2 +,则可以使用 UniqueConstraint。 你可以看到完整的答案here

【讨论】:

    猜你喜欢
    • 2013-07-04
    • 2021-08-05
    • 1970-01-01
    • 2010-10-26
    • 2022-10-05
    • 1970-01-01
    • 2019-04-14
    • 2019-05-15
    相关资源
    最近更新 更多