#27629: Inconsistent check of allow_relation in 
ForwardManyToOneDescriptor.__set__
-------------------------------------+-------------------------------------
               Reporter:  Sven       |          Owner:  nobody
  Coenye                             |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  1.10
  layer (models, ORM)                |       Keywords:  allow_relation
               Severity:  Normal     |  ForwardManyToOneDescriptor
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 The method in  django/db/models/fields/related_descriptors.py currently
 contains the following code:
 {{{
 if instance._state.db is None:
     instance._state.db = router.db_for_write(instance.__class__,
 instance=value)
 elif value._state.db is None:
     value._state.db = router.db_for_write(value.__class__,
 instance=instance)
 elif value._state.db is not None and instance._state.db is not None:
     if not router.allow_relation(value, instance):
         raise ValueError('Cannot assign "%r": the current database router
 prevents this relation.' % value)
 }}}

 When using an application containing the following model
 {{{
 from otherapp.models import AdProgram

 class Order(models.Model):
     first_name   = models.CharField(max_length = 15)
     last_name    = models.CharField(max_length = 20)
     program      = models.ForeignKey(AdProgram, db_constraint=False)    #
 No cross database FK constraints under MSSQL
 }}}

 where the imported model belongs to a legacy database different from the
 application's own database, the code in question does not flag an
 inappropriate relationship. E.g. when submitting a ModelForm containing
 these three fields, the value for program will be saved to the
 application's database even if allow_relation would return False.

 When the model definition is changed to
 {{{
 from otherapp.models import AdProgram, AdTerm

 class Order(models.Model):
     first_name   = models.CharField(max_length = 15)
     last_name    = models.CharField(max_length = 20)
     program      = models.ForeignKey(AdProgram, db_constraint=False)    #
 No cross database FK constraints under MSSQL
     term         = models.ForeignKey(AdTerm, db_constraint=False)
 }}}

 "program" again gets a free pass, but "term" triggers the ValueError
 exception.

 The reason is that instance._state.db is None for the "program" field but
 contains the value retrieved for "program" for any subsequent fields.

 I believe those "elif" statements should be plain "if" statements so the
 uninitialized value on the first pass does not fall through?

--
Ticket URL: <https://code.djangoproject.com/ticket/27629>
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 unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/050.da54449307169e4bb0449e58d9152b37%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to