Django - get_or_create не работает - PullRequest
       20

Django - get_or_create не работает

6 голосов
/ 17 августа 2011

Можете ли вы помочь мне понять, почему этот код вызывает повторяющуюся запись (IntegrityError)?

Я на Django 1.2.

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

У меня есть уникальное ограничение на field1. Если есть строка, где field1 = 1, все работает нормально, Django выполняет команду «get».

Если нет строки, где field1 = 1, похоже, что Django создает эту строку, и это нормально. Но почему это не позволяет мне сохранить его?

Обновление:

Если это поможет, вот моя модель:

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'

field1 - это внешний ключ для другой таблицы. Но я не делал модель в Django для этой таблицы, поэтому я не говорю Django, что это внешний ключ.

Ответы [ 3 ]

7 голосов
/ 18 августа 2011

Предполагая, что это достаточно точное представление вашего реального кода, неудивительно, что взломан не Django, а ваша модель.

Вы переопределили поле автоматического первичного ключа своим собственным полем id, ноупущено, чтобы сделать его автоинкрементом.Таким образом, база данных не использует новое значение для PK, поэтому возникает ошибка целостности.

Если у вас нет действительно веской причины, вам следует разрешить Django разобраться с самим полем PK.

3 голосов
/ 17 августа 2011

get_or_create звучит обанкротилось мне. Я просто делаю эту работу вокруг:

rows = MyModel.objects.filter(field1=1)
row = rows[0] if rows else MyModel(field1=1)
row.other_field = 2
row.save()
1 голос
/ 08 апреля 2014

Получить или Создать возвращает кортеж результатов, даже если используемое вами поле установлено в качестве первичного ключа или уникального.

Так что в вашем случае: строка - это кортеж с одним объектом, поэтому это должно работать для вас:

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