Code

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#7971 closed (invalid)

default doesn't work for foreign key fields

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

Description

Model:

class A(models.Model):
  id = models.CharField(primary_key=True, max_length=5)

class B(models.Model):
  a = models.ForeignKey(A, default=A)

Code:

>>> b = nags_models.B()
>>> b.a
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "/opt/django/db/models/fields/related.py", line 240, in __get__
    rel_obj = QuerySet(self.field.rel.to).get(**params)
  File "/opt/django/db/models/query.py", line 301, in get
    raise self.model.DoesNotExist("%s matching query does not exist."
DoesNotExist: A matching query does not exist.
>>> b.a = models.A()
>>> b.a
<A: A object>

Attachments (0)

Change History (2)

comment:1 Changed 6 years ago by russellm

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

I don't know what gave you the impression that this _should_ work, but it doesn't make any sense. default takes an instance, or a callable that returns an instance. 'A' is a class, so it can't be used as a default.

If you want to populate the field 'B.a' with a new instance of A, then you need to define a function that returns a new instance, and use that function as a callable value to default: e.g.:

def new_a():
    return A()

class B(models.Model):
    a = models.ForeignKey(A, default=new_a)

comment:2 Changed 6 years ago by mtredinnick

The main problem with the approach in the description -- even though A seems to satisfy the constraints of being a callable -- is that it would lead to a database integrity issue if it proceeded further. The A() instance has not been saved, so it does not have a corresponding row in the database table and thus trying to refer to that (non-existent) row from the B table would lead to trouble. Thus you have to use a function and also save the instance before returning it.

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.