Идея выше
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.
Я планирую переопределить метод 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 внедряет в этой области довольно много вуду через django.db.models.deletion.Collector.
Странно, что у инструмента modren, такого как Django, нет руководства по Optimictic Concurency Control.
Я обновлю этот пост, когда отгадаю загадку. Надеюсь, решение будет приятным питоническим способом, не связанным с тоннами кодирования, странными представлениями, пропуском важных частей Django и т. Д.
person
Kiril
schedule
31.07.2011