Domanda

Ho due modelli: Play e PlayParticipant, definito (in parte) come:

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

Un pezzo del mio codice ha un p gioco che ha id 8581, e vorrei aggiungere partecipanti ad esso. Sto cercando di usare .create() di RelatedManager per farlo, come:

p.playparticipant_set.create(player_id=2383)

Da cui, Django costrutti:

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

Si tratta di un bug in Django, o sto abusando .create()?

conchiglia copia-incolla per controllo di integrità:

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

Da query.log:

5572 Query       INSERT INTO `api_playparticipant` (`player_id`, `play_id`, `note`) VALUES (2383, 2383, '')
È stato utile?

Soluzione

Non vedo come è il tuo primo esempio dovrebbe essere un bug? Questo comportamento è del tutto intuitivo. Il vostro è un p giocare con ID 2383, e si sta chiamando il metodo sul suo insieme correlato creare. Sei anche specificando un campo aggiuntivo, chiamato player_id , e dandogli un valore di 2383. E 'logico che sia il gioco id sarà 2383 (perché questa è l'id del gioco che contiene questo insieme correlato) e quel giocatore id sarà anche 2383 (perché è stato passato in modo esplicito che il valore in).

Il secondo esempio sembrerebbe indicare un bug, ma non riesco a riprodurlo. Qui sono i miei modelli:

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)

Ecco l'output della shell:

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

In ogni caso, perché stai scrivendo questo per SO? Django ha un bugtracker, un paio di attivi mailing list ufficiali e un paio di canali IRC.

Altri suggerimenti

Si dovrebbe essere utilizzando un ManyToManyField nel modello di gioco che fa riferimento ai zero o più partecipanti. In quel codice si sarebbe solo essere facendo

play.players.add(player)

Non è un bug; controllare la documentazione ; in particolare la sezione campi extra su molti-a-molti . Esso specifica:

  

A differenza dei normali molti-a-molti campi, non è possibile utilizzare add, create, o assignment (vale a dire, beatles.members = [...]) per creare relazioni.

     

L'unico modo per creare questo tipo di rapporto è quello di creare istanze del modello intermedio.

Non riesco a riprodurre quel comportamento. Con modelli simili, posso fare funzionare:

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

e ottengo nuova p di Product, la cui p.manufacturer chiave esterna è uguale m esempio.

Questo è il Django-1.0.2 con PostgreSQL; quale versione di Django si usa, e che SQL backend?

Prova ad utilizzare due nuovi modelli minimali con il campo ForeignKey su uno di essi, che dovrebbe funzionare; poi fare questi modelli via via più vicino a modelli che mostrano il comportamento in mancanza. In questo modo è possibile isolare singola modifica che lo rende comportano male; questo cambiamento è la chiave per la ragione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top