0

Aと の2 つの外部キーを持つモデル ( ) がbありcます。

bINCLUDING NULLcを一緒に一意にする必要があります

したがってb、一度cだけ一緒に NULL にする必要があります

ただし、Django でこれを達成することはできません。ここに私がこれまでに持っているコードがあります。どんな助けでも大歓迎です!

-_-

class A(models.Model):
  b = models.ForeignKey('B', blank = True, null = True)
  c = models.ForeignKey('C', blank = True, null = True)

  class Meta:
    unique_together = (
      ('b', 'c')
    )

このコードは、データベースでこの望ましくない結果を生成します。

+----+------+------+
| id | b_id | c_id |
+----+------+------+
|  1 |    2 | 3    |
|  2 |    2 | 77   |
|  3 |    2 | NULL |
|  4 |    2 | NULL |
|  5 | NULL | NULL |
|  6 | NULL | NULL |
+----+------+------+

最初の 2 行は、django によって 1 回だけ挿入できます。これは素晴らしいです:)

ただし、残りの行は重複エントリであり、これを制限したいと思います。

アップデート

私は仕事を成し遂げる何かを見つけましたが、それは本当にハッキーなようです..何か考えはありますか?

class A(models.Model):
  def clean(self):
    from django.core.exceptions import ValidationError

    if not any([self.b, self.c]):
      if Setting.objects.filter(b__isnull = True, c__isnull = True).exists():
        raise ValidationError("Already exists")

    elif self.b and not self.c:
      if Setting.objects.filter(c__isnull = True, b = self.b).exists():
        raise ValidationError("Already exists")

    elif self.c and not self.user:
      if Setting.objects.filter(c = self.c, b__isnull = True).exists():
        raise ValidationError("Already exists")
4

3 に答える 3

1

より良い解決策があるかもしれませんが、次のことを行うことができます。

  1. 新しい属性dを作成し、結合する一般的な方法を見つけますb_id(c_idたとえばstr(b_id) + "*" + str(c_id)、モデルの作成時にこれを自動的に実行します (ここではシグナル メカニズムが役立つ場合があります))。
  2. dprimary_key として使用

これは解決策というより回避策ですが、うまくいくはずです。

もう1つの考え:インスタンスの作成/更新時に「Null」/「Null」の既存のインスタンスがあるかどうかを確認するオプションはありますか? これはデータベース レベルの問題を解決しませんが、ロジックは期待どおりに機能します。

于 2013-10-29T10:53:22.657 に答える