How do I tell Django to not create a table for an M2M related field?

纵然是瞬间 提交于 2019-12-08 08:14:50

问题


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?


回答1:


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.




回答2:


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.




回答3:


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)


来源:https://stackoverflow.com/questions/4907913/how-do-i-tell-django-to-not-create-a-table-for-an-m2m-related-field

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!