Opened 8 years ago

Closed 7 years ago

Last modified 7 years 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 8 years ago.

Download all attachments as: .zip

Change History (11)

by Keith Hostetler, 8 years ago

comment:1 by Keith Hostetler, 8 years ago

Type: UncategorizedBug

comment:2 by Keith Hostetler, 8 years ago

Description: modified (diff)

comment:3 by Tim Graham, 8 years ago

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 by Paulo, 7 years ago

Owner: changed from nobody to Paulo
Status: newassigned

comment:5 by Andrey Fedoseev, 7 years ago

Cc: Andrey Fedoseev added

comment:6 by Paulo, 7 years ago

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 by Berker Peksag, 7 years ago

Cc: Berker Peksag added

comment:9 by Tim Graham <timograham@…>, 7 years ago

Resolution: fixed
Status: assignedclosed

In a7b5ad8b:

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

comment:10 by Tim Graham <timograham@…>, 7 years ago

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