Django save () запускает INSERT вместо UPDATE: почему? - PullRequest
0 голосов
/ 20 мая 2019

Рассмотрим следующую модель Django:

class Outlet(models.Model):
    a = models.CharField(max_length=253, primary_key=True, db_index=True)
    def _split(self, idx):
        if not self.a:
            return None
        return self.a.split(".")[idx]
    @property
    def b(self):
        return self._split(0)
    @property
    def c(self):
        return self._split(1)

Пара с этим классом, зарегистрированным в admin:

@admin.register(Outlet)
class OutletAdmin(admin.ModelAdmin):
    fields = ("a", "b", "c")
    readonly_fields = ("b", "c")

Начните с пустой БД:

enter image description here

Добавьте один экземпляр в интерфейсе администратора:

enter image description here

enter image description here

Хорошо, пока.Теперь перейдите к изменению этого экземпляра:

enter image description here

enter image description here

Да?Что сейчас произошло?Django только что выполнил INSERT, когда можно с уверенностью ожидать, что он выполнит UPDATE.

Непосредственно с Как Django знает, как ОБНОВИТЬ против INSERT :

Вы можетезаметил, что объекты базы данных Django используют один и тот же метод save () для создания и изменения объектов.Джанго абстрагируется от необходимости использовать операторы SQL INSERT или UPDATE.В частности, когда вы вызываете save (), Django следует этому алгоритму:

  • Если для атрибута первичного ключа объекта задано значение, которое оценивается как True (т. Е. Значение, отличное от None, или пустая строка), Django выполняет UPDATE.
  • Если атрибут первичного ключа объекта не задан или если UPDATE ничего не обновлял, Django выполняет INSERT.

Now, этот вопрос скажет мне, что это потому, что a является первичным ключом.Во-первых, я не вижу такого упоминания в документации по Django.Во-вторых, я не могу удалить атрибут primary_key из a.

Меня больше интересует знание , почему это так, что вызвано внутренне с Django, и гдеэто задокументировано (если где-нибудь)? Существуют ли другие недокументированные условия, при которых INSERT выполняется, когда вы ожидаете ОБНОВЛЕНИЕ?

1 Ответ

3 голосов
/ 20 мая 2019

https://docs.djangoproject.com/en/2.2/ref/models/fields/#django.db.models.Field.primary_key

Поле первичного ключа доступно только для чтения. Если вы измените значение первичного ключа для существующего объекта, а затем сохраните его, новый объект будет создан вместе со старым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...