Opened 5 weeks ago

Closed 4 weeks ago

#36062 closed Bug (fixed)

Deserializing CompositePrimaryKey from a string raises raises ValueError

Reported by: Jacob Walls Owned by: Sarah Boyce
Component: Core (Serialization) Version: dev
Severity: Release blocker Keywords:
Cc: Csirmaz Bendegúz Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Adjusting this test (for a roundtrip from a serialized string and back) to use CompositePrimaryKey produces a failure:

  • tests/serializers/models/base.py

    diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py
    index e4fcee366d..63c3590113 100644
    a b class Actor(models.Model):  
    9999
    100100
    101101class Movie(models.Model):
     102    pk = models.CompositePrimaryKey("actor", "title", "price")
    102103    actor = models.ForeignKey(Actor, models.CASCADE)
    103104    title = models.CharField(max_length=50)
    104105    price = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal("0.00"))
ERROR: test_serialize_unicode_roundtrip (serializers.test_xml.XmlSerializerTestCase.test_serialize_unicode_roundtrip)
Unicode makes the roundtrip intact
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/.../django/tests/serializers/tests.py", line 241, in test_serialize_unicode_roundtrip
    obj_list = list(serializers.deserialize(self.serializer_name, serial_str))
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/.../django/django/core/serializers/xml_serializer.py", line 214, in __next__
    return self._handle_object(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/.../django/django/core/serializers/xml_serializer.py", line 289, in _handle_object
    obj = base.build_instance(Model, data, self.db)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/.../django/django/core/serializers/base.py", line 325, in build_instance
    return Model(**data)
           ^^^^^^^^^^^^^
  File "/Users/.../django/django/db/models/base.py", line 566, in __init__
    _setattr(self, prop, value)
  File "/Users/.../django/django/db/models/fields/composite.py", line 36, in __set__
    raise ValueError(f"{self.field.name!r} must be a list or a tuple.")
ValueError: 'pk' must be a list or a tuple.

----------------------------------------------------------------------
Ran 212 tests in 7.973s

FAILED (errors=1)

Other unit tests using other test models fail if adjusted in the same way, so this is not isolated to the xml serializer.

Change History (9)

comment:1 by Sarah Boyce, 4 weeks ago

Cc: Csirmaz Bendegúz added
Triage Stage: UnreviewedAccepted

Thank you!

comment:2 by Sarah Boyce, 4 weeks ago

Owner: set to Sarah Boyce
Status: newassigned
Summary: Deserializing CompositePrimaryKey from a string raises ValueErrorDeserializing CompositePrimaryKey from XML raises ValueError

comment:3 by Sarah Boyce, 4 weeks ago

Has patch: set

comment:4 by Jacob Walls, 4 weeks ago

Thanks for jumping on this, Sarah. This was buried at the bottom of the ticket, but there is a similar issue with the JSON and YAML serializers. For example, adjusting this test model fails produces more failures. Would you prefer a new ticket?

  • tests/serializers/models/base.py

    diff --git a/tests/serializers/models/base.py b/tests/serializers/models/base.py
    index e4fcee366d..a2e5aca323 100644
    a b class TeamField(models.CharField):  
    150150
    151151
    152152class Player(models.Model):
     153    pk = models.CompositePrimaryKey("name", "rank", "team")
    153154    name = models.CharField(max_length=50)
    154155    rank = models.IntegerField()
    155156    team = TeamField()

comment:5 by Sarah Boyce, 4 weeks ago

Patch needs improvement: set
Summary: Deserializing CompositePrimaryKey from XML raises ValueErrorDeserializing CompositePrimaryKey from a string raises raises ValueError

Ah sorry I missed that, let's keep it as one ticket

comment:6 by Simon Charette, 4 weeks ago

As pointed out on the PR we likely need to implement the proper value_to_string, value_from_object, and to_python methods for CompositePrimaryKey (docs) and ensure the serialization framework calls value_to_string instead of making direct str calls.

See how it's done for JSONField, postgres.ArrayField, and HStoreField for example.

comment:7 by Sarah Boyce, 4 weeks ago

Patch needs improvement: unset

comment:8 by Sarah Boyce, 4 weeks ago

Triage Stage: AcceptedReady for checkin

comment:9 by Sarah Boyce <42296566+sarahboyce@…>, 4 weeks ago

Resolution: fixed
Status: assignedclosed

In 6a1a9c0:

Fixed #36062 -- Handled serialization of CompositePrimaryKeys.

Note: See TracTickets for help on using tickets.
Back to Top