2011-08-17 13 views
6

puoi aiutarmi a capire perché questo codice causa una voce duplicata (IntegrityError)?Django - get_or_create non funziona

Sono su Django 1.2.

(row, is_new) = MyModel.objects.get_or_create(field1=1) 
row.other_field = 2 
row.save() 

Ho un vincolo univoco sul campo1. Se c'è una riga dove field1 = 1, tutto funziona bene, Django fa un "get".

Se non c'è una riga dove campo1 = 1, sembra che Django stia creando quella riga che è ok. Ma perché non mi permette di salvarlo?

Aggiornamento:

Se serve, qui è MyModel:

class MyModel(models.Model): 
    id = models.BigIntegerField(primary_key=True) 
    field1 = models.BigIntegerField(unique=True) 
    other_field = models.CharField(max_length=765) 
    class Meta: 
     db_table = u'project_crosses_suppl_FO' 

campo1 è una chiave esterna a un'altra tabella. Ma non ho fatto una modella in Django per quel tavolo, quindi non dico a Django che è una chiave straniera.

+0

non MyModel hanno campo straniera? Puoi pubblicare il codice di MyModel? –

+1

[Questa domanda simile] (http://stackoverflow.com/questions/6974463/django-get-or-create-raises-duplicate-entry-with-together-unique) potrebbe aiutarti. – agf

+0

@agf. Non capisco quale sia stata la risoluzione in questa domanda o come il problema sia giustificato. Sembra un bug per me. Penso che mi arrenderò su get_or_create e fare un lavoro in giro :-( – Greg

risposta

3

get_or_create suoni sballati. Sto solo facendo questo lavoro intorno:

rows = MyModel.objects.filter(field1=1) 
row = rows[0] if rows else MyModel(field1=1) 
row.other_field = 2 
row.save() 
7

Partendo dal presupposto che è una rappresentazione ragionevolmente fedele del codice vero e proprio, non a caso non è Django che è sballato, è il tuo modello.

Hai sovrascritto il campo della chiave primaria automatica con il tuo campo id, ma trascurato di renderlo un autoincremento. Quindi il database non sta usando un nuovo valore per il PK, quindi l'errore di integrità.

A meno che tu non abbia una buona ragione, dovresti lasciare che Django si occupi del campo PK stesso.

+1

Oh questo è un buon punto.E 'un tavolo esistente che non posso cambiare. perché sto dicendo a Django quale sia la chiave primaria, quindi cosa cambi esattamente? La colonna "id" nella tabella MySQL è effettivamente impostata su incremento automatico. Devo dire a Django che è un campo di incremento automatico? – Greg

+0

@ Greg, hai già provato questo? – Kirill

1

Ottieni o Crea restituisce una tupla di risultati anche se il campo che utilizzi è impostato come chiave primaria o unico.

Quindi nel tuo caso: Row è una tupla con un oggetto, quindi questo dovrebbe funzionare per voi:

(row, is_new) = MyModel.objects.get_or_create(field1=1) 
row[0].other_field = 2 
row[0].save() 
Problemi correlati