3

私は2つのモデルを持っています:PlayPlayParticipantは、(部分的に) 次のように定義されています:

class PlayParticipant(models.Model):
    player = models.ForeignKey('Player')
    play = models.ForeignKey('Play')
    note = models.CharField(max_length=100, blank=True)

コードの一部にpid 8581 の play があり、それに参加者を追加したいと考えています。私は.create()それを行うために RelatedManager を使用しようとしています:

p.playparticipant_set.create(player_id=2383)

そこから、Django は以下を構築します。

INSERT INTO `api_playparticipant` (`player_id`, `play_id`, `note`) VALUES (2383, 2383, '')

これは Django のバグですか、それとも誤用.create()ですか?

サニティチェック用のコピーペーストシェル:

In [17]: p = Play.objects.get(id=8581)

In [18]: p.id
Out[18]: 8581L

In [19]: p.playparticipant_set.create(player_id=2383)
...
IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails (`gc/api_playparticipant`, CONSTRAINT `play_id_refs_id_60804ffd462e0029` FOREIGN KEY (`play_id`) REFERENCES `api_play` (`id`))')

query.log から:

5572 Query       INSERT INTO `api_playparticipant` (`player_id`, `play_id`, `note`) VALUES (2383, 2383, '')
4

4 に答える 4

3

あなたの最初の例がどのようにバグであると思われるのかわかりませんか?この動作は完全に直感的です。pはIDが2383のプレイであり、関連するセットでcreateメソッドを呼び出しています。また、 player_idという追加のフィールドを指定し、それに2383の値を指定します。両方のプレイIDが2383(この関連セットを含むプレイのIDであるため)であり、そのプレーヤーIDも2383になるのは論理的です。 2383(明示的にその値を渡したため)。

2番目の例はバグを示しているように見えますが、再現できません。これが私のモデルです:

class Player(models.Model):
    name = models.CharField(max_length=100)

class Play(models.Model):
    title = models.CharField(max_length=100)

class PlayParticipant(models.Model):
    player = models.ForeignKey('Player')
    play = models.ForeignKey('Play')
    note = models.CharField(max_length=100, blank=True)

シェルの出力は次のとおりです。

>>> player1 = Player.objects.create()
>>> player2 = Player.objects.create()
>>> player1.id
2
>>> player2.id
3
>>> play1 = Play.objects.create()
>>> play2 = Play.objects.create()
>>> play1.id
3
>>> play2.id
4
>>> pp1 = play1.playparticipant_set.create(player_id=2)
>>> pp1.play.id
3
>>> pp1.player.id
2

とにかく、なぜこれをSOに投稿するのですか?Djangoには、バグトラッカー、いくつかのアクティブな公式メーリングリスト、およびいくつかのIRCチャネルがあります。

于 2009-07-15T18:10:13.250 に答える
1

ゼロ以上の参加者に関連する Play モデルで ManyToManyField を使用する必要があります。そのコードでは、あなたはただやっているでしょう

play.players.add(player)
于 2009-07-09T02:58:35.110 に答える
0

その振る舞いを再現することはできません。同様のモデルで、私は実行できます:

m = Manufacturer.objects.get(1)
p = m.product_set.create(name='23',category_id=1,price=23,delivery_cost=2)

そして、外部キーがに等しいの新しいインスタンスを取得しpます。Productp.manufacturerm

これはPostgreSQLを使用したDjango-1.0.2にあります。どのバージョンのDjangoを使用し、どのSQLバックエンドを使用していますか?

そのうちの1つにForeignKeyフィールドがある2つの新しい最小モデルを使用してみてください。これは機能するはずです。次に、これらのモデルを、失敗した動作を示すモデルに徐々に近づけます。このようにして、誤動作を引き起こす単一の変更を分離できます。この変更が理由の鍵です。

于 2009-07-18T18:45:15.570 に答える
0

これはバグではありません。ドキュメントを確認してください; 具体的には、多対多の関係に関する追加フ​​ィールドのセクションです。それは指定します:

通常の多対多フィールドとは異なり、、、、addまたはcreateassignmentつまりbeatles.members = [...])を使用して関係を作成することはできません。

このタイプの関係を作成する唯一の方法は、中間モデルのインスタンスを作成することです。

于 2009-07-15T02:00:26.393 に答える