Question

I'm using this little jewel of a Django code snippet to edit a ManyToManyField from both directions:

class ManyToManyField_NoSyncdb(models.ManyToManyField):  
    def __init__(self, *args, **kwargs):  
        super(ManyToManyField_NoSyncdb, self).__init__(*args, **kwargs)
        self.creates_table = False  

class Job(models.Model):  
    persons = ManyToManyField_NoSyncdb( Person, blank=True, db_table='person_jobs' )

(snippet details here)

It lets me select all the persons in a given job from the jobs form and inversely lets me select all the jobs for a person from the persons form and updates the single jobs_persons table in both cases.

Upon moving from Django 1.0 to 1.2, however, syncdb now generates a duplicate table error because creates_table is evidently no longer a supported property in the base class.

Is there another way to instruct Django 1.2 not to create a table for a RelatedField?

Was it helpful?

Solution

So, if you want to have access to the ManyToMany in both models in the Admin, currently the official solution is to use inlinemodel for the second model. I had also this same problem/need just a few days ago. And I was not really satisfied with the inlinemodel solution (heavy in DB queries if you have a lot of entries, cannot use the filter_horizontal widget, etc.).

The solution I found (that's working with Django 1.2+ and syncdb) is this:

class User(models.Model):
    groups = models.ManyToManyField('Group', through='UserGroups')

class Group(models.Model):
    users = models.ManyToManyField('User', through='UserGroups')

class UserGroups(models.Model):
    user_id = models.ForeignKey(User)
    group_id = models.ForeignKey(Group)

    class Meta:
        db_table = 'app_user_group'
        auto_created = User

See ticket 897 for more info.

Unfortunately, if you're using South you will have to remove the creation of the app_user_group table in every migration file created automatically.

OTHER TIPS

The "managed" meta option for models might be helpful. From http://docs.djangoproject.com/en/1.2/ref/models/options/#managed

If a model with managed=False contains a ManyToManyField that points to another unmanaged model, then the intermediate table for the many-to-many join will also not be created. However, the intermediary table between one managed and one unmanaged model will be created.

If you need to change this default behavior, create the intermediary table as an explicit model (with managed set as needed) and use the ManyToManyField.through attribute to make the relation use your custom model.

Let me post the new solution in Django's ticket #897, which mention by Etienne too. It work well in Django 1.2.

class Test1(models.Model):
    tests2 = models.ManyToManyField('Test2', blank=True)

class Test2(models.Model):
    tests1 = models.ManyToManyField(Test1, through=Test1.tests2.through, blank=True)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top