Opened 10 months ago
Closed 10 months 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): 99 99 100 100 101 101 class Movie(models.Model): 102 pk = models.CompositePrimaryKey("actor", "title", "price") 102 103 actor = models.ForeignKey(Actor, models.CASCADE) 103 104 title = models.CharField(max_length=50) 104 105 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 , 10 months ago
| Cc: | added |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
| Summary: | Deserializing CompositePrimaryKey from a string raises ValueError → Deserializing CompositePrimaryKey from XML raises ValueError |
comment:3 by , 10 months ago
| Has patch: | set |
|---|
comment:4 by , 10 months 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): 150 150 151 151 152 152 class Player(models.Model): 153 pk = models.CompositePrimaryKey("name", "rank", "team") 153 154 name = models.CharField(max_length=50) 154 155 rank = models.IntegerField() 155 156 team = TeamField()
comment:5 by , 10 months ago
| Patch needs improvement: | set |
|---|---|
| Summary: | Deserializing CompositePrimaryKey from XML raises ValueError → Deserializing CompositePrimaryKey from a string raises raises ValueError |
Ah sorry I missed that, let's keep it as one ticket
comment:6 by , 10 months 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 , 10 months ago
| Patch needs improvement: | unset |
|---|
comment:8 by , 10 months ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
Thank you!