Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@MarkusH
Last active December 9, 2015 13:27
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save MarkusH/ac4cf709be285c2660be to your computer and use it in GitHub Desktop.
Save MarkusH/ac4cf709be285c2660be to your computer and use it in GitHub Desktop.
Concurrent edit prevention through forms
from django import forms
from django.core.exceptions import ValidationError
from .models import Foo
class VersionNumberFormMixin(forms.Form):
version_number = forms.IntegerField(min_value=0, widget=forms.HiddenInput)
def __init__(self, *args, **kwargs):
super(VersionNumberFormMixin, self).__init__(*args, **kwargs)
if not self.instance.pk:
# We are working with a new object so force pre-initial version
self.instance.version_number = 0
self.initial['version_number'] = self.instance.version_number
def clean_version_number(self):
submitted = self.cleaned_data.get('version_number', 0)
given = self.instance.version_number
if given != submitted:
raise ValidationError('Invalid version', code='invalid')
return submitted
# Use it like this:
class FooForm(VersionNumberFormMixin, forms.ModelForm):
class Meta:
model = Foo
fields = ('name',)
from django.db import models
class VersionNumberMixin(models.Model):
version_number = models.PositiveIntegerField()
class Meta:
abstract = True
def save(self):
self.version_number += 1
super(VersionNumberMixin, self).save()
# Use it like this:
class Foo(VersionNumberMixin, models.Model):
name = models.CharField(max_length=20)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment