Идея выше
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()
отлично выглядит и отлично работает даже без сериализуемых сделок.
Проблема заключается в том, как увеличить поведение deafult .save(), поскольку не нужно выполнять ручную сантехнику, чтобы вызвать метод .update().
Я рассмотрел идею пользовательского менеджера.
Я планирую переопределить метод Manager _update, который вызывается Model.save_base() для выполнения обновления.
Это текущий код в Django 1.3
def _update(self, values, **kwargs):
return self.get_query_set()._update(values, **kwargs)
Что нужно сделать, ИМХО это что-то вроде:
def _update(self, values, **kwargs):
#TODO Get version field value
v = self.get_version_field_value(values[0])
return self.get_query_set().filter(Q(version=v))._update(values, **kwargs)
Похожие вещи должно произойти на удаление. Однако удаление немного сложнее, поскольку Django реализует довольно некоторое voodoo в этой области через django.db.models.deletion.Collector.
Странно, что у инструмента modren, такого как Django, отсутствует руководство для контроля устойчивости.
Я буду обновлять этот пост, когда решаю загадку. Надеюсь, решение будет в хорошем питоническом ключе, которое не включает в себя тонны кодирования, странные виды, пропуски основных частей Django и т. Д.
Если один объект может быть обновлен несколькими одновременными пользователями, у вас может возникнуть проблема с большим дизайном. Возможно, стоит подумать о ресурсах, специфичных для пользователя, или разделить этапы обработки на отдельные таблицы, чтобы это не было проблемой. – 2008-11-26 17:03:46