Opened 15 years ago

Last modified 2 years ago

#11541 assigned Bug

F() expressions don't allow assignment of Foreign Key values on instances

Reported by: Russell Keith-Magee Owned by: Aman Pandey
Component: Database layer (models, ORM) Version: 1.1-beta
Severity: Normal Keywords:
Cc: Abhijeet Viswa Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Lines 93-102 of the expressions model test define the following test case:

# F expressions cannot be used to update attributes which are foreign keys, or
# attributes which involve joins.
>>> test_gmbh.point_of_contact = None
>>> test_gmbh.save()
>>> test_gmbh.point_of_contact is None
True
>>> test_gmbh.point_of_contact = F('ceo')
Traceback (most recent call last):
...
ValueError: Cannot assign "<django.db.models.expressions.F object at ...>": "Company.point_of_contact" must be a "Employee" instance.

There's no reason this sort of assignment shouldn't be possible - it just requires the appropriate handling on the related field.

Change History (10)

comment:1 by Russell Keith-Magee, 15 years ago

Triage Stage: UnreviewedAccepted
Version: 1.01.1-beta-1

comment:2 by dc, 15 years ago

Saving FileField and ImageField with assigned F expression will also fail with

AttributeError: 'F' object has no attribute 'field'

comment:3 by Julien Phalip, 14 years ago

Severity: Normal
Type: Bug

comment:4 by Aymeric Augustin, 13 years ago

UI/UX: unset

Change UI/UX from NULL to False.

comment:5 by Aymeric Augustin, 13 years ago

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:6 by Abhijeet Viswa, 5 years ago

I gave a shot at fixing this ticket. However, I got stuck real fast. F expressions aren't resolved until the queryset is evaluated. However, the test to check if the right-value is an instance of the forward relation's class is performed during assignment. The only solution I could think of is to defer the test for F expressions until queryset evaluation.

Maintainers, would this be the best approach?

comment:7 by Abhijeet Viswa, 5 years ago

Cc: Abhijeet Viswa added

comment:8 by Simon Charette, 5 years ago

The only solution I could think of is to defer the test for F expressions until queryset evaluation.

Abhijeet, the check can likely be deferred if hasattr(value, resolve_expression).

comment:9 by Abhijeet Viswa, 5 years ago

Marten Kenbeek pointed out to me that Fexpression can be assigned to the attname attribute of the Model instance. So, test_gmbh.point_of_contact_id can be assigned F('ceo') to have the intended effect. However, I don't think this is documented. Would documenting this be enough to close this ticket? Or should F expressions be assignable to the relation descriptors?

comment:10 by Aman Pandey, 2 years ago

Owner: changed from nobody to Aman Pandey
Status: newassigned
Note: See TracTickets for help on using tickets.
Back to Top