Ticket #17879: ticket17439.patch

File ticket17439.patch, 3.5 KB (added by tmitchell, 3 years ago)

Test and fix

  • django/core/serializers/python.py

    diff --git a/django/core/serializers/python.py b/django/core/serializers/python.py
    index 6cdfc9f..195bf11 100644
    a b class Serializer(base.Serializer): 
    4747    def handle_fk_field(self, obj, field):
    4848        if self.use_natural_keys and hasattr(field.rel.to, 'natural_key'):
    4949            related = getattr(obj, field.name)
    50             value = related.natural_key()
     50            if related:
     51                value = related.natural_key()
     52            else:
     53                value = None
    5154        else:
    5255            value = getattr(obj, field.get_attname())
    5356        self._current[field.name] = value
  • tests/regressiontests/serializers_regress/models.py

    diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
    index f366f90..9d0d03a 100644
    a b class LengthModel(models.Model): 
    272272
    273273    def __len__(self):
    274274        return self.data
     275
     276class PersonManager(models.Manager):
     277    def get_by_natural_key(self, first_name, last_name):
     278        return self.get(first_name=first_name, last_name=last_name)
     279
     280class Person(models.Model):
     281    objects = PersonManager()
     282
     283    first_name = models.CharField(max_length=100)
     284    last_name = models.CharField(max_length=100)
     285
     286    class Meta:
     287        unique_together = (('first_name', 'last_name'),)
     288
     289    def natural_key(self):
     290        return (self.first_name, self.last_name)
     291
     292class Car(models.Model):
     293    owner = models.ForeignKey(Person, null=True)
     294
  • tests/regressiontests/serializers_regress/tests.py

    diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
    index 704e34b..9cd0344 100644
    a b from .models import (BooleanData, CharData, DateData, DateTimeData, EmailData, 
    4242    PositiveSmallIntegerPKData, SlugPKData, SmallPKData, USStatePKData,
    4343    AutoNowDateTimeData, ModifyingSaveData, InheritAbstractModel, BaseModel,
    4444    ExplicitInheritBaseModel, InheritBaseModel, ProxyBaseModel,
    45     ProxyProxyBaseModel, BigIntegerData, LengthModel, Tag, ComplexModel)
     45    ProxyProxyBaseModel, BigIntegerData, LengthModel, Tag, ComplexModel, Person, Car)
    4646
    4747# A set of functions that can be used to recreate
    4848# test data objects of various kinds.
    for format in serializers.get_serializer_formats(): 
    485485    setattr(SerializerTests, 'test_' + format + '_serializer_fields', curry(fieldsTest, format))
    486486    if format != 'python':
    487487        setattr(SerializerTests, 'test_' + format + '_serializer_stream', curry(streamTest, format))
     488
     489
     490class NaturalKeyTest(TestCase):
     491    def setUp(self):
     492        self.person = Person.objects.create(first_name='John', last_name='Doe')
     493
     494    def test_fk_to_natural_key_model(self):
     495        """This is included just for posterity"""
     496        obj = Car.objects.create(owner=self.person)
     497        string_data = serializers.serialize(format, [obj], use_natural_keys=True)
     498        self.assertEqual(string_data, '[{"pk": 1, "model": "serializers_regress.car", "fields": {"owner": ["John", "Doe"]}}]')
     499
     500    def test_null_fk_to_natural_key_model(self):
     501        obj = Car.objects.create()
     502        string_data = serializers.serialize(format, [obj], use_natural_keys=True)
     503        self.assertEqual(string_data, '[{"pk": 1, "model": "serializers_regress.car", "fields": {"owner": null}}]')
     504
Back to Top