Ідея вище
updated = Entry.objects.filter(Q(id=e.id) && Q(version=e.version))\
.update(updated_field=new_value, version=e.version+1)
if not updated:
raise ConcurrentModificationException()
виглядає чудово і повинен працювати нормально навіть без транзакцій, що піддаються серіалізації.
Проблема полягає в тому, як збільшити глуху поведінку .save (), щоб не потрібно було робити сантехніку вручну, щоб викликати метод .update ().
Я подивився ідею Custom Manager.
Мій план полягає в тому, щоб замінити метод _update Manager, який викликається Model.save_base () для виконання оновлення.
Це поточний код у Django 1.3
def _update(self, values, **kwargs):
return self.get_query_set()._update(values, **kwargs)
Що потрібно зробити IMHO, це щось на зразок:
def _update(self, values, **kwargs):
v = self.get_version_field_value(values[0])
return self.get_query_set().filter(Q(version=v))._update(values, **kwargs)
Подібне має відбуватися при видаленні. Однак видалити трохи складніше, оскільки Django реалізує досить багато вуду в цій області через django.db.models.deletion.Collector.
Дивно, що модрен-інструменту, як Django, не вистачає вказівок щодо оптимічного контролю надійності.
Я оновлю цю публікацію, коли розгадаю загадку. Будемо сподіватися, що рішення буде мати приємний пітонічний спосіб, який не передбачає тонн кодування, дивних поглядів, пропуску важливих частин Django тощо.