La idea de arriba
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()
se ve muy bien y debería funcionar bien incluso sin transacciones serializables.
El problema es cómo aumentar el comportamiento de .save () sordo para no tener que hacer plomería manual para llamar al método .update ().
Miré la idea del Administrador personalizado.
Mi plan es anular el método Manager _update al que llama Model.save_base () para realizar la actualización.
Este es el código actual en Django 1.3
def _update(self, values, **kwargs):
return self.get_query_set()._update(values, **kwargs)
Lo que hay que hacer en mi humilde opinión es algo como:
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)
Algo similar debe suceder al eliminar. Sin embargo, eliminar es un poco más difícil ya que Django está implementando algo de vudú en esta área a través de django.db.models.deletion.Collector.
Es extraño que una herramienta moderna como Django carezca de orientación para Optimictic Concurency Control.
Actualizaré esta publicación cuando resuelva el acertijo. Con suerte, la solución será de una manera pitónica agradable que no implique toneladas de codificación, vistas extrañas, omitir piezas esenciales de Django, etc.