2012-07-24 77 views
1

我在django上使用一組foreignkey關係在django上出現重複鍵完整性錯誤的細微錯誤。Django IntegrityError Foreignkey上的重複條目

我有以下功能:

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' 

回答

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() 
+0

它會是一種不錯的,如果Django的有一個update_or_create方法,但這似乎比我的方法更好的方法。謝謝! – ChrisBurnor 2012-07-25 18:26:10

+0

好的。奇怪的是,即使使用Django的get_or_create,這仍然會發生。我想也許是因爲沒有設置默認值,但即使默認值仍然存在。 – ChrisBurnor 2012-08-15 20:11:38