2011-08-17 10 views
6

możesz mi pomóc zrozumieć, dlaczego ten kod powoduje duplikat wpisu (IntegrityError)?Django - get_or_create nie działa

Jestem na Django 1.2.

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

Mam unikalne ograniczenie na pole1. Jeśli istnieje wiersz gdzie field1 = 1, wszystko działa poprawnie, Django robi "get".

Jeśli nie ma wiersza, gdzie pole1 = 1, wygląda na to, że Django tworzy ten wiersz, który jest w porządku. Ale dlaczego nie pozwolę mi go zapisać?

Aktualizacja:

Jeśli to pomoże, oto 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' 

pole1 jest klucz obcy do innej tabeli. Ale nie zrobiłem modelu w Django dla tego stołu, więc nie mówiłem Django, że jest to klucz obcy.

+0

Does MyModel mieć pole obcego? Czy możesz opublikować kod MyModel? –

+1

[To podobne pytanie] (http://stackoverflow.com/questions/6974463/django-get-or-create-raises-duplicate-entry-with-together-unique) może ci pomóc. – agf

+0

@agf. Nie rozumiem, jaka była rezolucja w tym pytaniu, ani jak problem jest uzasadniony. To brzmi jak błąd dla mnie. Myślę, że zrezygnuję z get_or_create i wykonam pracę :-( – Greg

Odpowiedz

3

get_or_create dźwięki odpadły mi. Robię to obejść:

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

Zakładając, że jest to dość wierna reprezentacja prawdziwego kodu, nic dziwnego, że nie jest Django, który jest złapany, to model.

Przesłoniłeś pole klucza podstawowego automatycznym swoim własnym polem id, ale zostało to pomijane, aby uczynić z niego autoinkrementację. Tak więc baza danych nie używa nowej wartości dla PK, stąd błąd integralności.

Jeśli nie masz naprawdę dobrego powodu, powinieneś pozwolić, aby Django zajmowało się samym polem PK.

+1

To dobrze, to jest istniejący stół, którego nie mogę zmienić. dlaczego mówię Django, co to jest klucz podstawowy Więc co dokładnie zmienię? Kolumna "id" w tabeli MySQL jest właściwie ustawiona na auto-inkrementację Czy muszę powiedzieć Django, że jest to pole auto-inkrementacji? – Greg

+0

@Greg, już to wypróbowałeś? – Kirill

1

Pobierz lub Utwórz zwraca krotkę wyników, nawet jeśli używane pole jest ustawione jako klucz podstawowy lub unikatowy.

Więc w twoim przypadku: rzędzie jest krotką z jednego obiektu, stąd ten powinien pracować dla Ciebie:

(row, is_new) = MyModel.objects.get_or_create(field1=1) 
row[0].other_field = 2 
row[0].save() 
Powiązane problemy