Opened 11 months ago

Closed 3 months ago

Last modified 3 months ago

#27846 closed Bug (fixed)

refresh_from_db() doesn't clear reverse OneToOneFields

Reported by: Keith Hostetler Owned by: Paulo
Component: Database layer (models, ORM) Version: 1.10
Severity: Normal Keywords: refresh_from_db OneToOneField
Cc: Andrey Fedoseev, Berker Peksag Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Keith Hostetler)

Sorry for the poor summary, it is difficult to explain in words. I have a project to demo this bug attached to this ticket, but I will try to explain the bug anyway in steps and the setup.

Setup:

  • 2 models (A and B)
  • B has a OneToOne to A
  • Both A and B have a field (ie TextField)
  • Setup either a signal or override save() for A to update B's TextField to equal that of A's on save() or post_save for signals

Steps:

  • Create instance of A
  • Get another copy of the instance of A via A.objects.get()
  • Create instance of B using the copy of the instance of A
  • Do refresh_from_db() on original instance of A
  • Try to access B from A

The project I have provided is a slim version of this problem that demonstrates it with signals, overriden save(), and basic set and save inside the test. The basic set and save works, but the other two fail when using the above steps. Run the test suite to see.

Attachments (1)

django_1_10_refresh_from_db_bug.rar (11.2 KB) - added by Keith Hostetler 11 months ago.

Download all attachments as: .zip

Change History (11)

Changed 11 months ago by Keith Hostetler

comment:1 Changed 11 months ago by Keith Hostetler

Type: UncategorizedBug

comment:2 Changed 11 months ago by Keith Hostetler

Description: modified (diff)

comment:3 Changed 11 months ago by Tim Graham

Summary: refresh_from_db() does not create "soft links" on model_instances that are pointed to by another model's OneToOneFieldrefresh_from_db() doesn't clear reverse OneToOneFields
Triage Stage: UnreviewedAccepted

I think this is fixable but I'm not sure without trying to write a patch. This case may be discussed in ticket:901#comment:36 It looks like the issue is that refresh_from_db() clears concrete fields but doesn't clear reverse relations.

comment:4 Changed 8 months ago by Paulo

Owner: changed from nobody to Paulo
Status: newassigned

comment:5 Changed 6 months ago by Andrey Fedoseev

Cc: Andrey Fedoseev added

comment:6 Changed 5 months ago by Paulo

Hello,
What do you all think about clearing the fields cache entirely on refresh_from_db()?
This would cover similar bugs where a many to one or many to many relationship is cached.
The only case we can't cover is fields prefetched to custom attributes.

comment:7 Changed 4 months ago by Berker Peksag

Cc: Berker Peksag added

comment:9 Changed 3 months ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In a7b5ad8b:

Fixed #27846 -- Made Model.refresh_from_db() clear cached relations.

comment:10 Changed 3 months ago by Tim Graham <timograham@…>

In 5d3f2aa:

[2.0.x] Fixed #27846 -- Made Model.refresh_from_db() clear cached relations.

Backport of a7b5ad8b19a08d7d57302ece74f6e26d2887fd9f from master

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