#25486: ORM generating incorrect query for through-model on 
<RelatedManager>.all()
----------------------------------------------+--------------------
     Reporter:  pembo13                       |      Owner:  nobody
         Type:  Bug                           |     Status:  new
    Component:  Database layer (models, ORM)  |    Version:  1.8
     Severity:  Normal                        |   Keywords:
 Triage Stage:  Unreviewed                    |  Has patch:  0
Easy pickings:  0                             |      UI/UX:  0
----------------------------------------------+--------------------
 I have a through-model which itself has a through model (because it needs
 a many-to-many relationship). The problem comes when i try to get related
 mode through this many-to-many relationship. The ORM generates the WHERE
 clause on the wrong field (the pk, instead of the fk).

 {{{
 #!sql
 -- generated sql
 SELECT "core_role"."id", "core_role"."name"
 FROM "core_role"
 INNER JOIN "core_dealercontactrole" ON ( "core_role"."id" =
 "core_dealercontactrole"."role_id" )
 WHERE "core_dealercontactrole"."id" = 8743
 ORDER BY "core_role"."name" ASC

 -- corrected sql
 SELECT "core_role"."id", "core_role"."name"
 FROM "core_role"
 INNER JOIN "core_dealercontactrole" ON ( "core_role"."id" =
 "core_dealercontactrole"."role_id" )
 WHERE "core_dealercontactrole"."dealercontact_id" = 8743
 ORDER BY "core_role"."name" ASC
 }}}

 The code that generated the query:

 {{{
 #!python
 dc = DealerContact.objects.get(id=8743)
 >>> unicode(dc.roles.all().query)
 u'SELECT "core_role"."id", "core_role"."name" FROM "core_role" INNER JOIN
 "core_dealercontactrole" ON ( "core_role"."id" =
 "core_dealercontactrole"."role_id" ) WHERE "core_dealercontactrole"."id" =
 8743 ORDER BY "core_role"."name" ASC'
 }}}

 Here are the models (with superfluous fields removed):

 {{{
 #!python
 class Contact(models.Model):

         first_name = models.CharField(blank=True, max_length=50)
         last_name = models.CharField(blank=True, max_length=50)

         class Meta:
                 ordering = ('last_name','first_name')

         pass

 class Dealer(models.Model):

         contacts = models.ManyToManyField('Contact',
 through='DealerContact', related_name='dealers')

         name = models.CharField(db_index=True, max_length=250)

         pass

 class DealerContact(models.Model):

         dealer = models.ForeignKey('Dealer',
 related_name='dealercontacts+', on_delete=models.CASCADE)
         contact = models.ForeignKey('Contact', related_name='+',
 on_delete=models.CASCADE)
         roles = models.ManyToManyField('Role',
 through='DealerContactRole', related_name='+')

         class Meta:
                 unique_together = ('dealer','contact')

         pass

 class DealerContactRole(models.Model):

         dealercontact = models.ForeignKey('DealerContact',
 related_name='+', on_delete=models.CASCADE)
         role = models.ForeignKey('Role', related_name='+')

         class Meta:
                 unique_together = ('dealercontact','role')

         pass

 class Role(models.Model):

         name = models.CharField(db_index=True, max_length=100)

         class Meta:
                 ordering = ('name',)

         pass
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/25486>
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.ebeef60f07a6c38806fd83ff33fc17e8%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to