1

一連の外部キー関係を持つ 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 が重複キーエラーを表示しています。これは、私が知る限り、そのインスタンスが 1 つしかない場合でも同様です。

参考までに、モデル定義は次のとおりです。

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'
4

1 に答える 1

2

まず、存在を確認する正しい式は次のとおりです。

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()
于 2012-07-24T17:28:58.563 に答える