#13030 closed (fixed)
Natural Key deserialization fails on foreign key to field that is itself a foreign key
Reported by: | yishaibeeri | Owned by: | nobody |
---|---|---|---|
Component: | Core (Serialization) | Version: | dev |
Severity: | Keywords: | natural keys | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Attached diff has a test showing this:
In (nonabstract) model inheritance, the child model's B primary key is not the usual integer, but rather a FK to the parent A.
Suppose model B has defined natural_key() and get_by_natural_key().
If a third model C has a field that is a foreign key to B, loading it using deserialization with natural keys will fail. During creation of the C instance (let's call it objC), this is what happens:
- First, the natural key will be used to successfully construct the instance of B (let's call it objB).
- Then, an assignment is made to set the relevant field of objC to point to objB. However, instead of the naive
objC.thefield = objB
, the actual assignment uses the relevant field.rel.field_name to do something along the lines of:field_name = field.rel.field_name objC.thefield_id = getattr(objB, field_name)
- In the usual case where field_name is a simple primary key (such as 'id'), this works nicely. However,
- when this field is in itself a foreignkey, the result from getattr is an object - the relevant objA(!). This of course throws a nasty exception.
I have not tried, but it appears this would fail in a similar fashion in any case where the target of the first FK (from objC) is itself an FK and not a simple field (even without involving inheritance).
Perhaps the naive approach (objC.thefield = objB
) would work better for all cases? This is a bit too deep for me, I'm afraid.
Attachments (1)
Change History (4)
by , 15 years ago
Attachment: | nk_inherit_test.diff added |
---|
comment:1 by , 15 years ago
milestone: | → 1.2 |
---|---|
Triage Stage: | Unreviewed → Accepted |
Thanks for the report - but most of all, thanks for the awesome ready-to-use test case.
comment:2 by , 15 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
diff with test showing bug