diff --git a/src/concurrency/fields.py b/src/concurrency/fields.py index 0e61a5e..c6b1157 100755 --- a/src/concurrency/fields.py +++ b/src/concurrency/fields.py @@ -333,7 +333,9 @@ def _get_hash(self, instance): check_fields = instance._concurrencymeta.check_fields ignore_fields = instance._concurrencymeta.ignore_fields - if check_fields is None: + if check_fields is None and ignore_fields is None: + fields = sorted([f.name for f in instance._meta.get_fields()]) + elif check_fields is None: fields = sorted([f.name for f in instance._meta.get_fields() if f.name not in ignore_fields]) else: diff --git a/tests/demoapp/demo/migrations/0002_conditionalversionmodelwithoutmeta.py b/tests/demoapp/demo/migrations/0002_conditionalversionmodelwithoutmeta.py new file mode 100644 index 0000000..1dd71e0 --- /dev/null +++ b/tests/demoapp/demo/migrations/0002_conditionalversionmodelwithoutmeta.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +from django.conf import settings +import concurrency.fields + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('demo', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='ConditionalVersionModelWithoutMeta', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', serialize=False, primary_key=True)), + ('version', concurrency.fields.ConditionalVersionField(default=1, help_text='record revision number')), + ('field1', models.CharField(unique=True, blank=True, max_length=30, null=True)), + ('field2', models.CharField(unique=True, blank=True, max_length=30, null=True)), + ('field3', models.CharField(unique=True, blank=True, max_length=30, null=True)), + ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True)), + ], + ), + ] diff --git a/tests/demoapp/demo/models.py b/tests/demoapp/demo/models.py index 1860d3d..69093e0 100644 --- a/tests/demoapp/demo/models.py +++ b/tests/demoapp/demo/models.py @@ -11,6 +11,7 @@ __all__ = ['SimpleConcurrentModel', 'AutoIncConcurrentModel', 'ProxyModel', 'InheritedModel', 'CustomSaveModel', 'ConcreteModel', 'TriggerConcurrentModel', + 'ConditionalVersionModelWithoutMeta', ] @@ -210,3 +211,17 @@ class Meta: class ConcurrencyMeta: check_fields = ['field1', 'field2', 'user'] + + +class ConditionalVersionModelWithoutMeta(models.Model): + """ + This model doesn't have ConcurrencyMeta defined. + """ + version = ConditionalVersionField() + field1 = models.CharField(max_length=30, blank=True, null=True, unique=True) + field2 = models.CharField(max_length=30, blank=True, null=True, unique=True) + field3 = models.CharField(max_length=30, blank=True, null=True, unique=True) + user = models.ForeignKey(User, null=True) + + class Meta: + app_label = 'demo' diff --git a/tests/demoapp/demo/settings.py b/tests/demoapp/demo/settings.py index 8f7598c..3fa2211 100644 --- a/tests/demoapp/demo/settings.py +++ b/tests/demoapp/demo/settings.py @@ -117,4 +117,6 @@ else: DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.sqlite3'}} + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': dbname, + }} diff --git a/tests/test_conditional.py b/tests/test_conditional.py index fda0d2c..7f1807d 100644 --- a/tests/test_conditional.py +++ b/tests/test_conditional.py @@ -8,7 +8,10 @@ from concurrency.exceptions import RecordModifiedError from concurrency.utils import refetch -from demo.models import ConditionalVersionModel +from demo.models import ( + ConditionalVersionModel, + ConditionalVersionModelWithoutMeta, +) logger = logging.getLogger(__name__) @@ -25,6 +28,15 @@ def instance(user): field2='1', field3='1')[0] +@pytest.fixture +def instance_no_meta(user): + return ConditionalVersionModelWithoutMeta.objects.create( + field1='1', + user=user, + field2='1', field3='1' + ) + + @pytest.mark.django_db def test_standard_save(instance): # only increment if checked field @@ -74,3 +86,17 @@ def test_save_allowed(instance): batch_instance.field3 = 'aaaa' batch_instance.save() instance.save() + + +@pytest.mark.django_db(transaction=True) +def test_conflict_no_meta(instance_no_meta): + # Scenario: batch change any field, + # the user is NOT ALLOWED to save + batch_instance = instance_no_meta.__class__.objects.get(pk=instance_no_meta.pk) + assert batch_instance.version == instance_no_meta.version + + batch_instance.field1 = 'aaaa' + batch_instance.save() + + with pytest.raises(RecordModifiedError): + instance_no_meta.save()