Cookbook¶
Unable to import data ?¶
Sometimes you need to temporary disable concurrency (ie during data imports)
Temporary disable per Model
from concurrency.api import disable_concurrency
with disable_concurrency(instance):
Model.object
Add version management to new models¶
models.py
from concurrency.fields import IntegerVersionField
class ConcurrentModel( models.Model ):
version = IntegerVersionField( )
tests.py
a = ConcurrentModel.objects.get(pk=1)
b = ConcurrentModel.objects.get(pk=1)
a.save()
b.save() # this will raise ``RecordModifiedError``
Add version management to Django and/or plugged in applications models¶
Concurrency can work even with existing models, anyway if you are adding concurrency management to an existing database remember to edit the database’s tables:
your_app.models.py
from django.contrib.auth import User
from concurrency.api import apply_concurrency_check
apply_concurrency_check(User, 'version', IntegerVersionField)
If used with Django>=1.7 remebber to create a custom migration.
Manually handle concurrency¶
Use concurrency_check
from concurrency.api import concurrency_check
class AbstractModelWithCustomSave(models.Model):
version = IntegerVersionField(db_column='cm_version_id', manually=True)
def save(self, *args, **kwargs):
concurrency_check(self, *args, **kwargs)
logger.debug(u'Saving %s "%s".' % (self._meta.verbose_name, self))
super(SecurityConcurrencyBaseModel, self).save(*args, **kwargs)
Test Utilities¶
ConcurrencyTestMixin offer a very simple test function for your existing models
from concurrency.utils import ConcurrencyTestMixin
from myproject.models import MyModel
class MyModelTest(ConcurrencyTestMixin, TestCase):
concurrency_model = TestModel0
concurrency_kwargs = {'username': 'test'}
Recover deleted record with django-reversion¶
Recovering delete record with diango-reversion produce a RecordModifeidError
.
As both pk and version are present in the object, django-concurrency try to load the record (that does not exists)
and this raises RecordModifedError
. To avoid this simply:
class ConcurrencyVersionAdmin(reversionlib.VersionAdmin):
def render_revision_form(self, request, obj, version, context, revert=False, recover=False):
with disable_concurrency(obj):
return super(ConcurrencyVersionAdmin, self).render_revision_form(request, obj, version, context, revert, recover)
or for (depending on django-reversion version)
class ConcurrencyVersionAdmin(reversionlib.VersionAdmin):
@disable_concurrency()
def recover_view(self, request, version_id, extra_context=None):
return super(ReversionConcurrentModelAdmin, self).recover_view(request,
version_id,
extra_context)