﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
11126	Admin model.ManyToManyField doesn't support  legacy db tables and custom model.ForeignKey fields	mwilson@…	nobody	"There appear to be issues using the models.ManyToManyFields with legacy database Xref tables if the referenced PK's are not named FIELD_ID in the Admin and/or the ORM layer.  Below find the example model.py file to simulate the problem and comments in the code showing how to setup the test and reproduce the behaviour I'm seeing.

Pertinants:
   * Using Postgres 8.3.  postgresql_psycopg2 driver.
   * Using Django trunk: rev 10787
   * App is called ""core"" so db tables are called core_TABLE

Test Case Setup:
   * models.py
{{{
class Blog(models.Model):
    pk_blog = models.IntegerField(primary_key=True, db_column=""pk_blog"", default=random.randint(1,10000000))
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __unicode__(self):
        return self.name

    class Admin:
        pass

class Author(models.Model):
    pk_author = models.IntegerField(primary_key=True, db_column=""pk_author"", default=random.randint(1,10000000))
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __unicode__(self):
        return self.name

    class Admin:
        pass
class Entry(models.Model):
    pk_entry = models.IntegerField(primary_key=True, db_column=""pk_entry"", default=random.randint(1,10000000))
    pk_blog = models.ForeignKey(Blog, db_column=""pk_blog"", to_field=""pk_blog"")
    headline = models.CharField(max_length=255)
    
        #### STEP 1:
        ### next line: leave this uncommented when you first generate the db tables
        ### via the manage.py syncdb command.  After that it should be commented out.
        ### Once syncdb is sucessfull we will be attempting to use the table that 
        ### is generated by the class EntryAuthor below. 
    authors = models.ManyToManyField(Author)
        ### NOTE: after doing a syncdb comment out this author definition and uncomment
        ### out the next one to start testing.  You may also want to drop the 
        ### core_entry_authors table that syncdb created as it isn't used.  We only
        ### use this definition just to get testing started and to have Django build
        ### tables easily for this test.   
    
        #### STEP 2: Try with db_table
        ### next line: if enabled once core_entry_author table is in place then
        ### you can't reference any custom fields on the db_table as the
        ### EntryAuthor model (see below) isn't referenced.  Additionally
        ### since the model isn't referenced Django assumes that the FK's in
        ### the XREF table (core_entry_author) are of the format field_id.
    #authors = models.ManyToManyField(Author, db_table='core_entry_author')
        ### SQL generated: SELECT ""core_author"".""pk_author"", ""core_author"".""name"", ""core_author"".""email"" FROM ""core_author"" INNER JOIN ""core_entry_author"" ON (""core_author"".""pk_author"" = ""core_entry_author"".""author_id"") WHERE ""core_entry_author"".""entry_id"" = 6557280
        #### NOTE: the incorrect usage of ""core_entry_author"".""author_id""
        #### Seems if you use the db_table parameter of M2M default FK field names
        #### are assumed.  Won't work in my case since this is a legacy table with
        #### Field names like pk_author (not author_id).  This won't work in this 
        #### situation.
        #### EXCEPTION: ProgrammingError: column core_entry_author.author_id does not exist LINE 1: ...ore_entry_author"" ON (""core_author"".""pk_author"" = ""core_entr...


        #### STEP 3: Try ""through"" paremeter.
        ### next line: if enabled once core_entry_author table is in place then
        ### the Authors M2M combo-box isn't visible in the Admin form for Entry
        ### Trying to get Django to understand the custom pk field names.
    #authors = models.ManyToManyField(Author, through='EntryAuthor')
        ### NOTES: The admin form has no Authors field!  Seems to be silently
        ### dropped from the form for some reason.  Admin form will let you save
        ### the record with no errors but no M2M relationship record is written
        ### to the core_entry_author xref table.
        ### This one is the one I think would be nice to get to work.   


    def __unicode__(self):
        return self.headline

    class Admin:
        pass

# NOTE: this class is only used by Django if M2M field def in Entry
# is specified as (Author, through='EntryAuthor').  This definition creates the test
# table core_entry_author.  You may want to drop the table created by the author M2M 
# definition above (called core_entry_authors)
class EntryAuthor(models.Model):
    pk_entry_author = models.IntegerField(primary_key=True, db_column=""pk_entry_author"", default=random.randint(1,10000000))
    pk_entry = models.ForeignKey(Entry, db_column=""pk_entry"")
    pk_author = models.ForeignKey(Author, db_column=""pk_author"")
    
    class Meta:
        db_table = 'core_entry_author'
        
    def __unicode__(self):
        return u'[%s]' % (self.pk_entry_author)

    class Admin:
        pass 

}}}

Discussion:


"		closed	contrib.admin	dev		invalid			Unreviewed	0	0	0	0	0	0
