Pomysł powyżej
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()
wygląda świetnie i powinien działać dobrze nawet bez transakcji, które można serializować.
Problem polega na tym, jak zwiększyć głuche zachowanie .save (), aby nie musieć wykonywać ręcznej instalacji hydraulicznej w celu wywołania metody .update ().
Spojrzałem na pomysł Custom Managera.
Planuję zastąpić metodę Manager _update wywoływaną przez Model.save_base () w celu przeprowadzenia aktualizacji.
To jest obecny kod w Django 1.3
def _update(self, values, **kwargs):
return self.get_query_set()._update(values, **kwargs)
Co należy zrobić IMHO to coś takiego:
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)
Podobnie musi się stać przy usuwaniu. Jednak usuwanie jest nieco trudniejsze, ponieważ Django implementuje sporo voodoo w tym obszarze poprzez django.db.models.deletion.Collector.
To dziwne, że modrenowe narzędzie, takie jak Django, nie ma wskazówek dotyczących Optimictic Concurency Control.
Zaktualizuję ten post, gdy rozwiążę zagadkę. Miejmy nadzieję, że rozwiązanie będzie w przyjemny, pythonowy sposób, który nie będzie wymagał mnóstwa kodowania, dziwnych widoków, pomijania podstawowych fragmentów Django itp.