سؤال

لدي نماذج: Play و PlayParticipant, ، المعرفة (جزئيا) على النحو التالي:

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

قطعة من التعليمات البرمجية لديها مسرحية p التي لديها معرف 8581، وأود أن أضيف المشاركين إليها. أحاول استخدام الصلة .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`))')

من Query.log:

5572 Query       INSERT INTO `api_playparticipant` (`player_id`, `play_id`, `note`) VALUES (2383, 2383, '')
هل كانت مفيدة؟

المحلول

لا أرى كيف يفترض أن يكون مثالك الأول خطأ؟ هذا السلوك سهل للغاية. لديك ص هو لعب مع معرف 2383، وأنت تدعو إلى طريقة إنشاء على مجموعة ذات صلة. أنت أيضا تحدد حقل إضافي، يسمى Player_id., ، وإعطائها قيمة 2383. من المنطقي فقط أن كلا معرف اللعب سيكون 2383 (نظرا لأن هذا هو معرف المسرحية التي تحتوي على مجموعة ذات صلة) وأن معرف اللاعب سيكون أيضا 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

في أي حال، لماذا ترنز هذا إلى ذلك؟ يحتوي Django على BugTracker، بضع قوائم بريدية رسمية نشطة وقنوات زوجين IRC.

نصائح أخرى

يجب أن تستخدم manytomanyfield في نموذج اللعب الذي يتعلق بالمشاركين الصفر أو أكثر. في هذا الرمز سوف تفعل فقط

play.players.add(player)

أنها ليست علة؛ افحص ال توثيق; ؛ على وجه التحديد القسم حقول إضافية على العديد من العلاقات. وبعد يحدد:

على عكس الحقول العادية للعديد من الحقول، لا يمكنك استخدامها add, create, ، أو assignment (بمعنى آخر، beatles.members = [...]) لخلق العلاقات.

الطريقة الوحيدة لإنشاء هذا النوع من العلاقات هي إنشاء مثيلات للنموذج المتوسط.

لا أستطيع إعادة إنتاج هذا السلوك. مع نماذج مماثلة، يمكنني تشغيل:

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

وأحصل على مثيل جديد p من Product, ، ملك من p.manufacturer مفتاح أجنبي يساوي m.

هذا على django-1.0.2 مع postgresql؛ أي إصدار من django تستخدمه، والذي sql backend؟

حاول استخدام نماذج جديدة اثنين جديدة مع حقل أخيرة على أحدهم، والتي يجب أن تعمل؛ ثم اجعل هذه النماذج أقرب إلى النماذج التي تظهر السلوك الفاشل. وبهذه الطريقة، يمكنك عزل تغيير واحد يجعل الأمر يسيئ الأمر. هذا التغيير هو مفتاح السبب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top