Alex Rivera | Logout

Django Bi-directional ManyToMany - How to prevent table creation on second model?

Asked 2011-02-03T00:34:40.403
18

I have two models, each has a shared ManyToMany, using the db_table field. But how do I prevent syncdb from attempting to create the shared table, for the second model?

class Model1(models.Model):
    othermodels = ManyToManyField('Model2', db_table='model1_model2', related_name='model1_model2')

class Model2(models.model):
    othermodels = ManyToManyField('Model1', db_table='model1_model2', related_name='model2_model1')

It's working great in my dev environment, because some of the tables got created piecemeal, as I built it all out. But from an empty database, syncdb throws: _mysql_exceptions.OperationalError: (1050, "Table 'model1_model2' already exists")

Is there a flag that I'm missing from the second model's field to prevent duplicate table creation? Or am I just doing this entirely wrong?

Edit
Report

1 Answer

3

In Django ManyToMany are bi-directional by default. The think is that you only have to define it on one model, not on both (and usually you don't need to give a name to the table):

class Model1(models.Model):
    othermodels = ManyToManyField('Model2')

class Model2(models.model):
    ...

That's it. Now syncdb will be happy. For more info: Django docs

The only drawback is, if you use the admin, you will have access to othermodels only in Model1.

Edit

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 Model1(models.Model):
    othermodels = models.ManyToManyField('Model2', through='Model1Model2')

class Model2(models.Model):
    othermodels = models.ManyToManyField('Model1', through='Model1Model2')

class Model1Model2(models.Model):
    model1 = models.ForeignKey(Model1)
    model2 = models.ForeignKey(Model2)

    class Meta:
        db_table = 'app_model1_model2'
        auto_created = Model1

See ticket 897 for more info.

Unfortunately, if you're using answered 2011-02-03T01:43:16.633

Your Answer