我有两个模型,每个模型都有一个共享的ManyToMany,使用db_table字段。但是,对于第二个模型,如何阻止syncdb尝试创建共享表?
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')
它在我的开发环境中工作得很好,因为有些表是零碎地创建的,因为我把它全部建成了。但是从一个空数据库中,syncdb抛出: _mysql_exceptions.OperationalError:(1050,“表'model1_model2'已存在”)
我是否在第二个模型的字段中缺少一个标志以防止重复创建表?或者我只是完全错了?
答案 0 :(得分:19)
我也找到了这个解决方案,对我来说非常有用:
class Test1(models.Model):
tests2 = models.ManyToManyField('Test2', blank=True)
class Test2(models.Model):
tests1 = models.ManyToManyField('Test1', through=Test1.tests2.through, blank=True)
答案 1 :(得分:5)
您无需在关系的两侧放置ManyToManyField
。 Django will do that for you
你可能想要更像这样的东西:
class Model1(models.Model):
name = models.CharField(max_length=128)
...
class Model2(models.Model):
name = models.CharField(max_length=128)
othermodels = models.ManyToManyField(Model1, through='Model1Model2')
...
class Membership(models.Model):
class Meta:
db_table = 'model1_model2'
model1 = models.ForeignKey(Model1)
model2 = models.ForeignKey(Model2)
当您使用模型时,Model1
的实例将有一个othermodels_set
字段,该字段由django自动添加。 Model2
的实例将othermodels
。
答案 2 :(得分:2)
class Awesome(models.Model):
one = models.TextField()
class Meta:
# Prevent table creation.
abstract = True
http://docs.djangoproject.com/en/dev/topics/db/models/#abstract-base-classes
这不是你想要的,但它是我所相信的最接近的。提出观点会不简单?
也许:
class Awesome(models.Model):
one = models.CharField(max_length = 255)
two = models.CharField(max_length = 255)
class AwesomeOne(Awesome):
fieldOne = models.ForeignKey(User, related_name = 'one')
class Meta:
abstract = True
class AwesomeTwo(Awesome):
fieldTwo = models.ForeignKey(User, related_name = 'two')
class Meta:
abstract = True
然后,您可以创建一个表并覆盖__getattr__
以阻止对原始字段的访问。
答案 3 :(得分:1)
在Django中,ManyToMany默认是双向的。我们认为你只需要在一个模型上定义它,而不是在两个模型上定义它(通常你不需要给表格命名):
class Model1(models.Model):
othermodels = ManyToManyField('Model2')
class Model2(models.model):
...
就是这样。现在syncdb
会很开心。有关详细信息:Django docs
唯一的缺点是,如果您使用管理员,则只能在othermodels
中访问Model1
。
因此,如果您想要在Admin中的两个模型中访问ManyToMany,那么官方解决方案是使用inlinemodel作为第二个模型。几天前我也有同样的问题/需要。我对 inlinemodel 解决方案并不满意(如果你有很多条目,不能使用* filter_horizontal *小部件等,那么DB查询会很重要。)
我找到的解决方案(使用Django 1.2+和syncdb
)是这样的:
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
有关详情,请参阅票证897。
不幸的是,如果您使用South,则必须在自动创建的每个迁移文件中删除app_model1_model2
表的创建。