#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 [email protected].
To post to this group, send email to [email protected].
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