#8892: ForeignKey relation not saved as expected
-------------------------------------+-------------------------------------
               Reporter:  julien     |          Owner:  blacklwhite
                   Type:  Bug        |         Status:  new
              Milestone:             |      Component:  Database layer
                Version:  1.0        |  (models, ORM)
             Resolution:             |       Severity:  Normal
           Triage Stage:  Ready for  |       Keywords:
  checkin                            |      Has patch:  1
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
Changes (by blacklwhite):

 * has_patch:  0 => 1
 * ui_ux:   => 0
 * easy:   => 0
 * stage:  Accepted => Ready for checkin


Comment:

 I fixed the bug as follows. If you save a model with a foreign key to a
 model which is not saved until this point, django will show an error:

 {{{
 >>> a = ModelA(name="a")
 >>> b = ModelB(name="b")
 >>> a.b = b
 >>> a.save()
 Traceback (most recent call last):
   File "<console>", line 1, in <module>
   File "django\db\models\base.py", line 492, in save
     self.save_base(using=using, force_insert=force_insert,
 force_update=force_update)
   File "django\db\models\base.py", line 521, in save_base
     self.refresh_foreign_keys()
   File "django\db\models\base.py", line 475, in refresh_foreign_keys
     ". Have you already saved the " + str(fk_ref) + " object?")
 ValueError: Cannot find a primary key for b as a foreign key in an
 instance
  of ModelA. Have you already saved the b object?
 }}}

 If you save a related model '''after''' setting the related one to the
 first object, it works as expected.

 {{{
 >>> a = ModelA(name="a")
 >>> b = ModelB(name="b")
 >>> a.b = b
 >>> b.save()
 >>> a.save()
 }}}

 ----

 Problems I've considered (sometimes I use id as synonym for the foreign
 key of an object):
 * Compatible to users accessing to the foreign key field as follows:
 {{{
 >>> a = ModelA(name="a")
 >>> b = ModelB(name="b")
 >>> b.save()
 >>> a.b = b
 >>> a.b_id
 }}}
 So it is neccessary to set the id to a_id during the __set__ method of a.b
 = b. However the assertion that the id of b is the same as a.b_id must be
 before writing a to the database.

 * Not loading the related object from the database.
 {{{
 >>> a = ModelA.objects.get(name="a")
 >>> a.name = "b"
 >>> a.save()
 }}}
 The instance of Object b will not be loaded from the database to reduce
 db-queries.

 * This patch does only try to set the primary key of the related object,
 if no primary key is set and a related object exists. In this way it will
 never do an additional database query. Of course it produces an overhead
 for every call of the save() method, but by comparison to the following
 database-query it is negligible.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/8892#comment:9>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com.
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to