Install & Compatibility
Where this runs
tested against v2.8.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.915 runs
installs and imports cleanly · install 0.0s · import 0.000s · 18.1MB
glibcpy 3.10–3.915 runs
installs and imports cleanly · install 1.8s · import 0.000s · 19MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
NAME
✓ from concurrency import NAME
✗ from concurrency.fields import IntegerVersionField
VERSION
✓ from concurrency import VERSION
✗ from concurrency.fields import IntegerVersionField
This quickstart demonstrates how to add an `IntegerVersionField` to a Django model to enable optimistic locking. It shows a basic scenario where two users attempt to update the same record, and the second save correctly raises a `RecordModifiedError`, preventing data loss. Remember to add 'concurrency' to your `INSTALLED_APPS`.
import os
import django
from django.conf import settings
from django.db import models
from concurrency.fields import IntegerVersionField
from concurrency.exceptions import RecordModifiedError
# Minimal Django settings for a runnable example
settings.configure(
INSTALLED_APPS=[
'django.contrib.auth',
'django.contrib.contenttypes',
'concurrency', # Required for django-concurrency
__name__ # For models in this file
],
DATABASES={'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:'}},
USE_TZ=True # Required by Django 3.2+
)
django.setup()
class Product(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
version = IntegerVersionField()
class Meta:
app_label = __name__ # Link model to this module as an app
def __str__(self):
return self.name
# Create tables (usually done with manage.py migrate)
from django.core.management import call_command
from io import StringIO
out = StringIO()
err = StringIO()
call_command('makemigrations', __name__, interactive=False, stdout=out, stderr=err)
call_command('migrate', interactive=False, stdout=out, stderr=err)
# --- Usage Example ---
# 1. Create a new product
p = Product.objects.create(name="Original Product")
print(f"Initial product: {p.name}, version: {p.version}")
# 2. Simulate User A loading and modifying the product
p_user_a = Product.objects.get(pk=p.pk)
p_user_a.name = "Product updated by User A"
p_user_a.save()
print(f"User A saved: {p_user_a.name}, version: {p_user_a.version}")
# 3. Simulate User B loading the product (before User A saved)
# and attempting to save their changes after User A.
p_user_b = Product.objects.get(pk=p.pk) # Still has version 1 from load
p_user_b.name = "Product updated by User B"
try:
p_user_b.save()
except RecordModifiedError:
print(f"\nERROR: User B's save failed due to concurrency conflict!")
print(f"Original version: {p_user_b.version}, current in DB: {Product.objects.get(pk=p.pk).version}")
print("User B would need to reload and re-apply changes.")
# Verify the final state in the database
final_product = Product.objects.get(pk=p.pk)
print(f"\nFinal product in DB: {final_product.name}, version: {final_product.version}")
Upgrade
Version history
2.8.1latest on PyPI · released Apr 8, 2026
Audit
Dependencies
DjangorequiredCore framework dependency, requires Django>=3.2.
sixrequiredCompatibility layer, though mostly a no-op for modern Python versions required by this library.