Die Idee oben
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()
sieht gut aus und sollte auch ohne serialisierbare Transaktionen gut funktionieren.
Das Problem besteht darin, wie das taube Verhalten von .save () erweitert werden kann, damit keine manuelle Installation durchgeführt werden muss, um die Methode .update () aufzurufen.
Ich habe mir die Idee des Custom Managers angesehen.
Mein Plan ist es, die von Model.save_base () aufgerufene Manager _update-Methode zu überschreiben, um das Update durchzuführen.
Dies ist der aktuelle Code in Django 1.3
def _update(self, values, **kwargs):
return self.get_query_set()._update(values, **kwargs)
Was IMHO getan werden muss, ist so etwas wie:
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)
Ähnliches muss beim Löschen passieren. Das Löschen ist jedoch etwas schwieriger, da Django über django.db.models.deletion.Collector in diesem Bereich ziemlich viel Voodoo implementiert.
Es ist seltsam, dass Modren-Tools wie Django keine Anleitung für Optimictic Concurency Control haben.
Ich werde diesen Beitrag aktualisieren, wenn ich das Rätsel löse. Hoffentlich wird die Lösung auf eine nette pythonische Art und Weise sein, die nicht jede Menge Codierung, seltsame Ansichten, das Überspringen wesentlicher Teile von Django usw. beinhaltet.