Opened 16 years ago

Last modified 13 years ago

#8279 closed

Models with multiple ManyToManyField to 'self' use the last table for every m2m — at Initial Version

Reported by: Alberto García Hierro <fiam@…> Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

class Entry(models.Model):

more_fields
related = models.ManyToManyField('self', verbose_name=_('related entries'))
translations = models.ManyToManyField('self', verbose_name=_('translations'))

From the database (postgres):

blango=# select * from blango_entry_related;

id | from_entry_id | to_entry_id


1 | 27 | 29
2 | 29 | 27
3 | 27 | 30
4 | 30 | 27
5 | 27 | 38
6 | 38 | 27

(6 rows)

blango=# select * from blango_entry_translations;

id | from_entry_id | to_entry_id


3 | 4 | 3
4 | 3 | 4
7 | 8 | 7
8 | 7 | 8

11 | 13 | 12
12 | 12 | 13

(6 rows)

blango=#

And from ./manage.py shell:
In [2]: from blango.models import *;Entry.objects.get(pk=27).related.all()
Out[2]: []
In [3]: from blango.models import *;Entry.objects.get(pk=27).translations.all()
Out[3]: []

The database query log indicates that Django is using the wrong table:
2008-08-12 22:38:10 CEST LOG: statement: SELECT "blango_entry"."id", "blango_entry"."title", "blango_entry"."slug", "blango_entry"."author_id", "blango_entry"."language_id", "blango_entry"."body", "blango_entry"."body_html", "blango_entry"."pub_date", "blango_entry"."draft", "blango_entry"."allow_comments" FROM "blango_entry" INNER JOIN "blango_entry_translations" ON ("blango_entry"."id" = "blango_entry_translations"."to_entry_id") WHERE "blango_entry_translations"."from_entry_id" = 27

If I change the order of the m2m in the model to:

class Entry(models.Model):

more_fields
translations = models.ManyToManyField('self', verbose_name=_('translations'))
related = models.ManyToManyField('self', verbose_name=_('related entries'))

Then I get all the related entries as related and as translations.

If it serves as help, I've added a print statement in django/db/models/fields/related.py at line 776:

...
775 else:
776 print '%s_%s' % (opts.db_table, self.name)
777 return '%s_%s' % (opts.db_table, self.name)
...

Which prints:

In [1]: from blango.models import *;Entry.objects.get(pk=27).related.all()
blango_entry_related
blango_entry_translations
Out[1]: []

In [2]: from blango.models import *;Entry.objects.get(pk=27).related.all()
blango_entry_related
Out[2]: []

Change History (0)

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