Opened 3 weeks ago

Closed 2 weeks ago

#37239 closed Bug (fixed)

Saving related objects with generated primary keys doesn't update assigned relations

Reported by: Jacob Walls Owned by: Jacob Walls
Component: Database layer (models, ORM) Version: 5.2
Severity: Normal Keywords:
Cc: Lily Foote 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

With these models:

class DBDefaultsFunctionPK(models.Model):
    uuid = models.UUIDField(primary_key=True, db_default=UUID4())

    class Meta:
        required_db_features = {
            "supports_uuid4_function",
            "supports_expression_defaults",
        }


class DBDefaultsFunctionPKChild(DBDefaultsFunctionPK):
    parent = models.OneToOneField(
        DBDefaultsFunctionPK,
        models.CASCADE,
        primary_key=True,
        db_default=UUID4(),
        related_name="child",
    )

    class Meta:
        required_db_features = {
            "supports_uuid4_function",
            "supports_expression_defaults",
        }

This test fails:

    @skipUnlessDBFeature(
        "can_return_rows_from_bulk_insert",
        "supports_expression_defaults",
        "supports_uuid4_function",
    )
    def test_foreign_key_db_default_expression_via_parent(self):
        parent = DBDefaultsFunctionPK()
        obj = DBDefaultsFunctionPKChild(parent=parent)
        parent.save()
        obj.save()
        self.assertEqual(obj.pk, parent.pk)
======================================================================
FAIL: test_foreign_key_db_default_expression_via_parent (field_defaults.tests.DefaultTests.test_foreign_key_db_default_expression_via_parent)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jwalls/django/tests/field_defaults/tests.py", line 152, in test_foreign_key_db_default_expression_via_parent
    self.assertEqual(obj.pk, parent.pk)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
AssertionError: UUID('fdfe6046-e662-4c36-a2e1-b10677d0ccb3') != UUID('ddeef3dd-52bc-4b35-b643-4634876a4acc')

----------------------------------------------------------------------
Ran 1 test in 0.016s

FAILED (failures=1, errors=1)

A similar version of the test using Now() instead of UUID4() fails on 5.2 (since UUID4() is not available there), but I ran into issues with trying to use datetimes in FK constraints on sqlite, so I'm happy to take advice on the best examples to build these models with, as I could be glazing over something obviously better.


This is the "separate non-release-blocker ticket" mentioned in #37238, and the underlying reason for the relaxed assertions on the PR for it.

Change History (7)

comment:1 by Jacob Walls, 3 weeks ago

Has patch: set

comment:2 by Sarah Boyce, 3 weeks ago

Cc: Lily Foote added
Triage Stage: UnreviewedAccepted

Thank you!

comment:3 by Sarah Boyce, 3 weeks ago

Patch needs improvement: set

comment:4 by Sarah Boyce, 3 weeks ago

Summary: After assigning a related object with a db_default, the db_default expression is reevaluated when saving the other objectSaving related objects with generated primary keys doesn't update assigned relations

I have closed #37238 as a duplicate as the fix for this appears to resolve that issue.
That ticket gives different example models we could use that wouldn't use UUID4

comment:5 by Jacob Walls, 3 weeks ago

Patch needs improvement: unset

comment:6 by Sarah Boyce, 2 weeks ago

Triage Stage: AcceptedReady for checkin

comment:7 by Jacob Walls <jacobtylerwalls@…>, 2 weeks ago

Resolution: fixed
Status: assignedclosed

In cef2346a:

Fixed #37239 -- Cleared stale db_default when pk comes from related object.

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