From d004dcac3fa73270d93705e2db2de13334a6af50 Mon Sep 17 00:00:00 2001 From: Iacopo Spalletti Date: Thu, 17 Feb 2022 22:58:35 +0100 Subject: [PATCH 1/2] Add support for cross-db lock tokens By dropping genericforeignky and replacing it with a property we can now create tokens for tables outside the default database --- lock_tokens/managers.py | 11 ++++++++++- lock_tokens/models.py | 5 ++++- lock_tokens/views.py | 3 ++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lock_tokens/managers.py b/lock_tokens/managers.py index 4dfc0bc..e63dba9 100644 --- a/lock_tokens/managers.py +++ b/lock_tokens/managers.py @@ -6,6 +6,14 @@ class LockTokenManager(Manager): + def create(self, **kwargs): + locked_object = kwargs.pop("locked_object", None) + if locked_object: + contenttype = ContentType.objects.get_for_model(locked_object) + kwargs["locked_object_content_type"] = contenttype + kwargs["locked_object_id"] = locked_object.pk + return super().create(**kwargs) + def get_for_object(self, obj, allow_expired=True): contenttype = ContentType.objects.get_for_model(obj) return self.get_for_contenttype_and_id(contenttype, obj.pk, allow_expired) @@ -23,7 +31,8 @@ def get_or_create_for_object(self, obj): try: return (self.get_for_object(obj, allow_expired=False), False) except self.model.DoesNotExist: - return (self.create(locked_object=obj), True) + contenttype = ContentType.objects.get_for_model(obj) + return (self.create(locked_object_content_type=contenttype, locked_object_id=obj.pk), True) class LockableModelManager(Manager): diff --git a/lock_tokens/models.py b/lock_tokens/models.py index 15e5f9f..51e0e2c 100644 --- a/lock_tokens/models.py +++ b/lock_tokens/models.py @@ -32,7 +32,6 @@ class LockToken(models.Model): ContentType, on_delete=models.CASCADE ) locked_object_id = models.CharField(max_length=100) - locked_object = GenericForeignKey("locked_object_content_type", "locked_object_id") locked_at = models.DateTimeField(editable=False, default=timezone.now) objects = LockTokenManager() @@ -50,6 +49,10 @@ def renew(self): self.locked_at = timezone.now() self.save() + @property + def locked_object(self): + return self.manager.get_for_contenttype_and_id(self.locked_object_content_type, self.locked_object_id) + def serialize(self): return { "token": self.token_str, diff --git a/lock_tokens/views.py b/lock_tokens/views.py index fc3a60e..c1cbc8d 100644 --- a/lock_tokens/views.py +++ b/lock_tokens/views.py @@ -30,7 +30,8 @@ def get_contenttype_or_404(self, app_label, model): def get_object_or_404(self, app_label, model, object_id): contenttype = self.get_contenttype_or_404(app_label, model) try: - return contenttype.get_object_for_this_type(pk=object_id) + model_class = contenttype.model_class() + return model_class.objects.get(pk=object_id) except contenttype.model_class().DoesNotExist: raise Http404("The object with id %s does not exist" % object_id) From 96c518ec2c564f2a78290ef7d92b3a7d123197b7 Mon Sep 17 00:00:00 2001 From: Iacopo Spalletti Date: Thu, 17 Feb 2022 23:00:51 +0100 Subject: [PATCH 2/2] Release 0.2.6.dev2 --- lock_tokens/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lock_tokens/__init__.py b/lock_tokens/__init__.py index 3219e2d..f993453 100644 --- a/lock_tokens/__init__.py +++ b/lock_tokens/__init__.py @@ -1 +1 @@ -__version__ = "0.2.6.dev1" +__version__ = "0.2.6.dev2"