3

我有两个模型:PlayPlayParticipant,(部分)定义为:

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

我的一段代码有一个pid 为 8581 的 play,我想向其中添加参与者。我正在尝试使用 RelatedManager.create()来做到这一点,例如:

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`))')

从查询.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(因为您明确地传递了该值)。

您的第二个示例似乎表明存在错误,但我无法重现它。这是我的模型:

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 有一个 bugtracker、几个活跃的官方邮件列表和几个 IRC 频道。

于 2009-07-15T18:10:13.250 回答
1

您应该在 Play 模型中使用与零个或多个参与者相关的 ManyToManyField。在那个代码中,你只是在做

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

这不是错误;检查文档;特别是关于多对多关系的额外字段部分。它规定:

与普通的多对多字段不同,您不能使用add, create, 或assignment(ie, beatles.members = [...]) 创建关系。

创建这种类型的关系的唯一方法是创建中间模型的实例。

于 2009-07-15T02:00:26.393 回答
0

我无法重现这种行为。使用类似的模型,我可以运行:

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

我得到了 的新实例pProduct其外p.manufacturer键等于m

这是在带有 PostgreSQL 的 Django-1.0.2 上;您使用哪个版本的 Django,以及哪个 SQL 后端?

尝试在其中一个上使用两个带有 ForeignKey 字段的新最小模型,这应该可以;然后使这些模型逐渐接近表现出失败行为的模型。通过这种方式,您可以隔离导致其行为不端的单个更改;这种变化是关键原因。

于 2009-07-18T18:45:15.570 回答