From 66b62192e21ea1eeaaedc49e12806fe94c2202c1 Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Thu, 14 May 2020 13:55:09 -0400 Subject: [PATCH 1/7] [-] CrudEvent object_id as a `CharField` --- .../migrations/0014_auto_20200513_0008.py | 18 ++++++ easyaudit/models.py | 2 +- easyaudit/signals/model_signals.py | 12 ++-- easyaudit/tests/db.sqlite3 | Bin 225280 -> 323584 bytes ...uidforeignkey_testuuidm2m_testuuidmodel.py | 61 ++++++++++++++++++ easyaudit/tests/test_app/models.py | 42 ++++++++++++ easyaudit/tests/test_app/tests.py | 44 +++++++++---- easyaudit/tests/test_app/urls.py | 6 ++ easyaudit/tests/test_app/views.py | 47 ++++++++++++-- 9 files changed, 207 insertions(+), 25 deletions(-) create mode 100644 easyaudit/migrations/0014_auto_20200513_0008.py create mode 100644 easyaudit/tests/test_app/migrations/0003_testbigintforeignkey_testbigintm2m_testbigintmodel_testuuidforeignkey_testuuidm2m_testuuidmodel.py diff --git a/easyaudit/migrations/0014_auto_20200513_0008.py b/easyaudit/migrations/0014_auto_20200513_0008.py new file mode 100644 index 00000000..bd858508 --- /dev/null +++ b/easyaudit/migrations/0014_auto_20200513_0008.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.6 on 2020-05-13 00:08 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('easyaudit', '0013_auto_20190723_0126'), + ] + + operations = [ + migrations.AlterField( + model_name='crudevent', + name='object_id', + field=models.CharField(max_length=255), + ), + ] diff --git a/easyaudit/models.py b/easyaudit/models.py index da8c870b..80fd6760 100644 --- a/easyaudit/models.py +++ b/easyaudit/models.py @@ -19,7 +19,7 @@ class CRUDEvent(models.Model): ) event_type = models.SmallIntegerField(choices=TYPES) - object_id = models.IntegerField() # we should try to allow other ID types + object_id = models.CharField(max_length=255) content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE, db_constraint=False) object_repr = models.TextField(null=True, blank=True) object_json_repr = models.TextField(null=True, blank=True) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index 3581edd3..e510ae68 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -62,14 +62,16 @@ def pre_save(sender, instance, raw, using, update_fields, **kwargs): # We need a better way for this to work. ManyToMany will fail on pre_save on create return None - if instance.pk is None: - created = True - else: + # Query the object, see if it exists + try: + old_model = sender.objects.get(id=instance.pk) created = False + except (sender.DoesNotExist, ): + old_model = None + created = True # created or updated? - if not created: - old_model = sender.objects.get(pk=instance.pk) + if old_model: delta = model_delta(old_model, instance) if not delta and getattr(settings, "DJANGO_EASY_AUDIT_CRUD_EVENT_NO_CHANGED_FIELDS_SKIP", False): return False diff --git a/easyaudit/tests/db.sqlite3 b/easyaudit/tests/db.sqlite3 index 842e9747959812fb19070a853eabf62a8f464dff..0acde42598d14e4a5924d136936158d81a47dc5c 100644 GIT binary patch literal 323584 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 z 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 N*0Om1rFK;R{{fXW()IuV delta 7353 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 Ne3W}MbmdTM{|{!NFGT Date: Sun, 17 May 2020 14:04:17 -0400 Subject: [PATCH 2/7] [-] Use `pk` instead of `id` in pre_save object lookup --- easyaudit/signals/model_signals.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index e510ae68..f470d3f2 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -64,7 +64,7 @@ def pre_save(sender, instance, raw, using, update_fields, **kwargs): # Query the object, see if it exists try: - old_model = sender.objects.get(id=instance.pk) + old_model = sender.objects.get(pk=instance.pk) created = False except (sender.DoesNotExist, ): old_model = None From cadc9dc30c55a6859f884712c420a8fd695b9112 Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Sun, 17 May 2020 20:04:53 -0400 Subject: [PATCH 3/7] [-] Fixes issue w/ post_delete / Adds delete test --- easyaudit/signals/model_signals.py | 5 ++++- easyaudit/tests/test_app/tests.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index f470d3f2..a150fc9c 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -302,6 +302,9 @@ def post_delete(sender, instance, using, **kwargs): user = None c_t = ContentType.objects.get_for_model(instance) + # object id to be used later + obj_id = instance.pk + def crud_flow(): try: with transaction.atomic(using=DATABASE_ALIAS): @@ -311,7 +314,7 @@ def crud_flow(): 'object_repr': str(instance), 'object_json_repr': object_json_repr, 'content_type_id': c_t.id, - 'object_id': instance.pk, + 'object_id': obj_id, 'user_id': getattr(user, 'id', None), 'datetime': timezone.now(), 'user_pk_as_string': str(user.pk) if user else user diff --git a/easyaudit/tests/test_app/tests.py b/easyaudit/tests/test_app/tests.py index 34818ba7..72b699f8 100644 --- a/easyaudit/tests/test_app/tests.py +++ b/easyaudit/tests/test_app/tests.py @@ -90,6 +90,16 @@ def test_fake_update(self): obj.save() self.assertEqual(2, crud_event_qs.count()) + def test_delete(self): + obj = self.Model.objects.create() + crud_event_qs = CRUDEvent.objects.filter(object_id=obj.id, content_type=ContentType.objects.get_for_model(obj)) + self.assertEqual(1, crud_event_qs.count()) + + obj_id = obj.pk + obj.delete() + crud_event_qs = CRUDEvent.objects.filter(object_id=obj_id, content_type=ContentType.objects.get_for_model(obj)) + self.assertEqual(2, crud_event_qs.count()) + class TestAuditUUIDModels(TestAuditModels): Model = TestUUIDModel From e97a2adf51e454c6c9bb75febae0abd44dcbef78 Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Mon, 18 May 2020 09:02:11 -0400 Subject: [PATCH 4/7] [-] Adds updates from #141 PR --- easyaudit/signals/model_signals.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index a150fc9c..266bfe1d 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -6,6 +6,7 @@ from django.contrib.auth.models import AnonymousUser from django.contrib.contenttypes.models import ContentType from django.core import serializers +from django.core.exceptions import ObjectDoesNotExist from django.db import transaction from django.db.models import signals from django.utils import timezone @@ -62,16 +63,21 @@ def pre_save(sender, instance, raw, using, update_fields, **kwargs): # We need a better way for this to work. ManyToMany will fail on pre_save on create return None - # Query the object, see if it exists - try: - old_model = sender.objects.get(pk=instance.pk) - created = False - except (sender.DoesNotExist, ): - old_model = None + # Determine if the instance is a create + if instance.pk is None: created = True + else: + created = False + try: + old_model = sender.objects.get(pk=instance.pk) + created = False + except ObjectDoesNotExist: + # This can happen when a model is saved as part of a Transaction. It then has + # a pk set but is actually created. + created = True # created or updated? - if old_model: + if not created: delta = model_delta(old_model, instance) if not delta and getattr(settings, "DJANGO_EASY_AUDIT_CRUD_EVENT_NO_CHANGED_FIELDS_SKIP", False): return False From 8ddce1970eba0b1fe5a331ceddcfd0a14ad69b6e Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Thu, 28 May 2020 15:39:10 -0400 Subject: [PATCH 5/7] [-] Removes the need for an explicit query - Uses the internal `_state` object --- easyaudit/signals/model_signals.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/easyaudit/signals/model_signals.py b/easyaudit/signals/model_signals.py index 266bfe1d..e0da6c88 100644 --- a/easyaudit/signals/model_signals.py +++ b/easyaudit/signals/model_signals.py @@ -64,20 +64,11 @@ def pre_save(sender, instance, raw, using, update_fields, **kwargs): return None # Determine if the instance is a create - if instance.pk is None: - created = True - else: - created = False - try: - old_model = sender.objects.get(pk=instance.pk) - created = False - except ObjectDoesNotExist: - # This can happen when a model is saved as part of a Transaction. It then has - # a pk set but is actually created. - created = True + created = instance.pk is None or instance._state.adding # created or updated? if not created: + old_model = sender.objects.get(pk=instance.pk) delta = model_delta(old_model, instance) if not delta and getattr(settings, "DJANGO_EASY_AUDIT_CRUD_EVENT_NO_CHANGED_FIELDS_SKIP", False): return False From 123e79a66c17789e4b6cf0bc2d808a69c4e8b98a Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Thu, 28 May 2020 21:30:50 -0400 Subject: [PATCH 6/7] [-] Adds `_state` compat test --- easyaudit/tests/test_app/tests.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/easyaudit/tests/test_app/tests.py b/easyaudit/tests/test_app/tests.py index 485ed509..4be0f2f3 100644 --- a/easyaudit/tests/test_app/tests.py +++ b/easyaudit/tests/test_app/tests.py @@ -25,6 +25,15 @@ TEST_ADMIN_PASSWORD = 'password' +@override_settings(TEST=True) +class TestDjangoCompat(TestCase): + + def test_model_state(self): + """Ensures models have the internal `_state` object.""" + inst = TestModel() + self.assertTrue(hasattr(inst, '_state')) + + @override_settings(TEST=True) class TestAuditModels(TestCase): Model = TestModel From 523f0a10b1a6f47d440cb49fe7a97d6a22cec306 Mon Sep 17 00:00:00 2001 From: Jose Soares Date: Mon, 20 Jul 2020 11:02:14 -0400 Subject: [PATCH 7/7] [-] Removes sqlite3 test db --- easyaudit/tests/db.sqlite3 | Bin 323584 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 easyaudit/tests/db.sqlite3 diff --git a/easyaudit/tests/db.sqlite3 b/easyaudit/tests/db.sqlite3 deleted file mode 100644 index 0acde42598d14e4a5924d136936158d81a47dc5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 323584 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 z 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 N*0Om1rFK;R{{fXW()IuV