我在django上出现了一个带有一组外键关系重复密钥完整性错误的细微错误。
我有以下功能:
def update_relationship(actor, action, status, target):
existing = Relation.objects.filter(actor=actor, target=target)
# If this relation is 'on', turn it off
if Relation.objects.filter(actor=actor, target=target, status=status):
Relation.objects.filter(actor=actor, target=target).update(status="")
# If this relationship is not on, turn it on
else:
created = True
if existing:
existing.update(status=status)
else:
Relation.objects.create(actor=actor, target=target, status=status)
正如您所看到的,我正在测试是否已存在于数据库中,然后在存在时更新它,如果不存在则创建新行。但是,似乎在某些条件下我无法重现,Django给了我一个重复的键错误,即使条件是,据我所知,只有一个例子。
供参考,以下是模型定义:
class Relation(models.Model):
Status = Choices(('L', 'Like', 'Like'),
('D', 'Dislike', 'Dislike'),
('S', 'Save', 'Save'))
actor = models.ForeignKey('members.Member', related_name='relations')
target = models.ForeignKey('members.Member', related_name='reverse_relations')
status = models.CharField(choices=Status, max_length=10)
created = models.DateTimeField('created', auto_now_add=True)
notified = models.BooleanField(default=False)
notified_mutual = models.BooleanField(default=False)
class Meta:
unique_together = (('actor', 'target'),)
ordering = ('created',)
verbose_name = 'Relation'
verbose_name_plural = 'Relations'
答案 0 :(得分:2)
首先,检查existence的正确表达式是:
existing = Relation.objects.filter(actor=actor, target=target).exists()
但djano编写句子的方法是使用get_or_create方法,是您正在寻找的方法:
Relation.objects.get_or_create(actor=actor, target=target,
defaults={ 'status':status }
)
或者,对于您的情况,例如:
r, _ = Relation.objects.get_or_create(actor=actor, target=target )
r.status = '' if r.status == 'on' else status
r.save()