Code

Opened 4 years ago

Closed 4 years ago

#12708 closed (invalid)

Django raises DoesNotExist when consulting an empty ForeignKey field

Reported by: lsaffre Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Keywords: ForeignKey DoesNotExist
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

"""

Django raises DoesNotExist when consulting an empty ForeignKey field

We create an Order without a Journal::
  
  >>> o = Order()
  >>> print o.journal
  None
  >>> o.save()
 
This works only because `Order.journal` has `null=True`.
In fact I want the `save()` method to complain if `journal` is empty,
so I remove `null=True` from the field definition.

  >>> o = Order2()
  >>> print o.journal
  None
  
The above line raises a DoesNotExist exception. Django should raise 
an exception only when I try to save the instance, not already when 
I want to see the value of `journal`!

"""

from django.db import models
   
class Journal(models.Model):
    pass

class Order(models.Model):
    journal = models.ForeignKey(Journal,null=True)

class Order2(models.Model):
    journal = models.ForeignKey(Journal)

Attachments (0)

Change History (1)

comment:1 Changed 4 years ago by lukeplant

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

I think the behaviour is consistent. If the journal_id attribute was set to an id which did not exist in the database, then you would get the same DoesNotExist behaviour. It is also symmetric with the behaviour of trying to set o.journal, which results in an exception.

To put simply, None is never the value of non-nullable foreign key object - you cannot set or get None as the value. If you want the foreign key value, rather than the object, use journal_id, not journal.

I've persuaded myself that this behaviour is intended and good, and changing it could be a significant backwards incompatibility anyway, so I'm closing INVALID.

Cheers.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.