diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/serializers/models/natural.py | 17 | ||||
| -rw-r--r-- | tests/serializers/test_natural.py | 35 |
2 files changed, 52 insertions, 0 deletions
diff --git a/tests/serializers/models/natural.py b/tests/serializers/models/natural.py index cfc57b1127..f32d781a76 100644 --- a/tests/serializers/models/natural.py +++ b/tests/serializers/models/natural.py @@ -2,6 +2,7 @@ import uuid +from django.contrib.auth.base_user import AbstractBaseUser from django.db import models @@ -74,3 +75,19 @@ class FKAsPKNoNaturalKey(models.Model): def natural_key(self): raise NotImplementedError("This method was not expected to be called.") + + +class SubclassNaturalKeyOptOutUser(AbstractBaseUser): + email = models.EmailField(unique=False, null=True, blank=True) + USERNAME_FIELD = "email" + + def natural_key(self): + return () + + +class PostToOptOutSubclassUser(models.Model): + author = models.ForeignKey(SubclassNaturalKeyOptOutUser, on_delete=models.CASCADE) + title = models.CharField(max_length=100) + subscribers = models.ManyToManyField( + SubclassNaturalKeyOptOutUser, related_name="subscribed_posts", blank=True + ) diff --git a/tests/serializers/test_natural.py b/tests/serializers/test_natural.py index b5b35708c6..322abeb7fc 100644 --- a/tests/serializers/test_natural.py +++ b/tests/serializers/test_natural.py @@ -9,6 +9,8 @@ from .models import ( NaturalKeyAnchor, NaturalKeyThing, NaturalPKWithDefault, + PostToOptOutSubclassUser, + SubclassNaturalKeyOptOutUser, ) from .tests import register_tests @@ -250,6 +252,34 @@ def fk_as_pk_natural_key_not_called(self, format): self.assertEqual(obj.object.pk, o1.pk) +def natural_key_opt_out_test(self, format): + """ + When a subclass of AbstractBaseUser opts out of natural key serialization + by returning an empty tuple, both FK and M2M relations serialize as + integer PKs and can be deserialized without error. + """ + user1 = SubclassNaturalKeyOptOutUser.objects.create(email="user1@example.com") + user2 = SubclassNaturalKeyOptOutUser.objects.create(email="user2@example.com") + + post = PostToOptOutSubclassUser.objects.create( + author=user1, title="Post 2 (Subclass Opt-out)" + ) + post.subscribers.add(user1, user2) + + user_data = serializers.serialize(format, [user1], use_natural_primary_keys=True) + post_data = serializers.serialize(format, [post], use_natural_foreign_keys=True) + + list(serializers.deserialize(format, user_data)) + deserialized_posts = list(serializers.deserialize(format, post_data)) + + post_obj = deserialized_posts[0].object + self.assertEqual(user1.email, post_obj.author.email) + self.assertEqual( + sorted([user1.email, user2.email]), + sorted(post_obj.subscribers.values_list("email", flat=True)), + ) + + # Dynamically register tests for each serializer register_tests( NaturalKeySerializerTests, @@ -284,3 +314,8 @@ register_tests( "test_%s_fk_as_pk_natural_key_not_called", fk_as_pk_natural_key_not_called, ) +register_tests( + NaturalKeySerializerTests, + "test_%s_natural_key_opt_out", + natural_key_opt_out_test, +) |
