如何告诉Django不为M2M相关字段创建表?

时间:2011-02-05 16:03:03

标签: django manytomanyfield

我正在使用这个Django代码片段的小宝石从两个方向编辑ManyToManyField:

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' )

(摘要详情here

它允许我从作业表单中选择给定作业中的所有人员,然后反过来让我从人员表单中选择一个人的所有作业,并在两种情况下更新单个jobs_persons表。

从Django 1.0迁移到1.2时,syncdb现在会生成重复的表错误,因为在基类中,creates_table显然不再是受支持的属性。

是否有另一种方法可以指示Django 1.2不为RelatedField创建表?

3 个答案:

答案 0 :(得分:2)

模型的“托管”元选项可能会有所帮助。来自http://docs.djangoproject.com/en/1.2/ref/models/options/#managed

  

如果包含managed = False的模型   一个指向的ManyToManyField   另一个非托管模型,然后是   中间表为   多对多的加入也不会   创建。但是,中介   一个托管和一个托管之间的表   将创建非托管模型。

     

如果您需要更改此默认值   行为,创造中介   表作为显式模型(带有   根据需要管理设置并使用   ManyToManyField.through属性为   使关系使用您的自定义   模型。

答案 1 :(得分:1)

因此,如果您想要在Admin中的两个模型中访问ManyToMany,那么官方解决方案是使用inlinemodel作为第二个模型。几天前我也有同样的问题/需要。我对 inlinemodel 解决方案并不满意(如果你有很多条目,不能使用filter_horizontal小部件等,那么数据库查询很重要。)。

我找到的解决方案(使用Django 1.2+和syncdb)是这样的:

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

有关详情,请参阅票证897

不幸的是,如果您使用South,则必须在自动创建的每个迁移文件中删除app_user_group表的创建。

答案 2 :(得分:1)

让我在Django的#897号门票中发布new solution,这也是Etienne提到的。它在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)