Opened 9 years ago

Closed 9 years ago

#13574 closed (duplicate)

ManyToManyFields using through won't respect to_field parameter in ForeignKey fields

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


When a ManyToManyField is set to use an existing model with through, Django will fail to generate the correct SQL if a ForeignKey in this model is using to_field to relate to a field other than the primary key of the target table. That happens because m2m handling code is always assuming that the relation if with the target table primary key.

For models like the following:

class Author(models.Model):
    name = models.CharField(max_length=50, unique=True)

class Book(models.Model):
    title = models.CharField(max_length=50, unique=True)
    authors = models.ManyToManyField(Author, through='BookToAuthor')

class BookToAuthor(models.Model):
    author = models.ForeignKey(Author, db_column='author_name', to_field='name')
    book = models.ForeignKey(Book, db_column='book_title', to_field='title')

The generated SQL for an book object (id = 1) access to authors attribute is

SELECT `author`.`id`, `author`.`name` FROM `author` INNER JOIN `booktoauthor` ON (`author`.`id` = `booktoauthor`.`author_name`) WHERE `booktoauthor`.`book_title` = 1

while the expected one is

SELECT `author`.`id`, `author`.`name` FROM `author` INNER JOIN `booktoauthor` ON (`author`.`name` = `booktoauthor`.`author_name`) INNER JOIN `book` ON (`booktoauthor`.`book_title` = `book`.`title`) WHERE `book`.`id` = 1

I attach a patch that uses the relation field_name attribute instead of assuming that the primary key is to be used.

Attachments (2)

django_m2m_field_name.diff (3.4 KB) - added by aitorciki 9 years ago.
django_m2m_field_name_regressiontest.diff (2.0 KB) - added by aitorciki 9 years ago.

Download all attachments as: .zip

Change History (3)

Changed 9 years ago by aitorciki

Attachment: django_m2m_field_name.diff added

Changed 9 years ago by aitorciki

comment:1 Changed 9 years ago by Ramiro Morales

Resolution: duplicate
Status: newclosed

Duplicate of #13343 that was closed in favor of #11319. I will add a note there pointing to this ticket.

Note: See TracTickets for help on using tickets.
Back to Top