gpt4 book ai didi

database - Django 自定义唯一在一起约束

转载 作者:太空狗 更新时间:2023-10-30 01:49:25 24 4
gpt4 key购买 nike

我有一个用户共享模型,如下所示:

class Share( models.Model ):
sharer = models.ForeignKey(User, verbose_name=_("Sharer"), related_name='sharer')
receiver = models.ForeignKey(User, verbose_name=_("Receiver"), related_name='receiver')

class Meta:
unique_together = ( ("sharer", "receiver"), ("receiver", "sharer") )

我想为 sharer(S) 和 receiver(R) 保存一个对象(顺序与 R-S 或 S-R 无关)。但在 unique_together 之上将无法实现这一点;假设 R-S 在数据库中,然后如果我保存 S-R,我将不会得到验证。为此,我为 Share 模型编写了自定义唯一验证。

    def validate_unique(
self, *args, **kwargs):
super(Share, self).validate_unique(*args, **kwargs)
if self.__class__.objects.filter( Q(sharer=self.receiver, receiver=self.sharer) ).exists():
raise ValidationError(
{
NON_FIELD_ERRORS:
('Share with same sharer and receiver already exists.',)
}
)

def save(self, *args, **kwargs):
# custom unique validate
self.validate_unique()
super(Share, self).save(*args, **kwargs)

这种方法在正常使用中效果很好。

问题:我有一个匹配算法,它获取共享和接收方的请求并保存共享对象(S-R 或 R-S)然后向它们发送响应(共享对象)几乎同时。由于我正在使用查询(无数据库级别)检查重复项,因此需要时间,所以最后我有 2 个对象 S-R 和 R-S。

我想要一些解决方案,对于共享者 S 和接收者 R,我只能保存单个共享对象,S-R 或 R-S 否则会出现一些验证错误(如数据库的 IntegrityError)。

Django=1.4,数据库=Postgresql

最佳答案

您可能可以使用 postgresql 的表达式索引 来解决这个问题,但这是另一种方法:

class Share( models.Model ):
sharer = models.ForeignKey(User)
receiver = models.ForeignKey(User), related_name='receiver')
key = models.CharField(max_length=64, unique=True)

def save(self, *args, **kwargs):
self.key = "{}.{}".format(*sorted([self.sharer_id, self.receiver_id]))
super(Share, self).save(*args, **kwargs)

但如果您使用 QuerySet.update 方法更改值,它显然不会起作用。你也可以看看 django-denorm ,它用触发器解决了这个问题。

关于database - Django 自定义唯一在一起约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15219938/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com