Python 如何使用现有数据库覆盖Django中的M2M字段名和模型?
我正在使用Django3.1.3并使用现有的postgresql数据库。此数据库的大多数模型和字段名称选择不当和/或太长。大多数情况下,使用一些方便的Django选项可以轻松更改它们,如:Python 如何使用现有数据库覆盖Django中的M2M字段名和模型?,python,django,postgresql,django-rest-framework,field,Python,Django,Postgresql,Django Rest Framework,Field,我正在使用Django3.1.3并使用现有的postgresql数据库。此数据库的大多数模型和字段名称选择不当和/或太长。大多数情况下,使用一些方便的Django选项可以轻松更改它们,如: class NewModelName(models.Models): new_field_name = models.CharField(max_length=50, db_column='old_field_name') class Meta: managed=False
class NewModelName(models.Models):
new_field_name = models.CharField(max_length=50, db_column='old_field_name')
class Meta:
managed=False
db_table='database_old_table_name'
但假设我想更改M2M字段名和相应的模型名。我想要一些像:
class Foo(models.Models):
new_m2m_field_name = models.ManyToManyField('RelatedModel', blank=True, db_column='old_m2m_field_name')
class Meta:
managed=False
db_table='foo_old_table_name'
class RelatedModel(models.Models):
name = models.CharField(max_length=50)
class Meta:
managed=False
db_table='related_model_old_table_name'
但如果我这样做,Django将抛出一个错误声明
django.db.utils.ProgrammingError:关系foo_new_m2m_field_name不存在。这就像忽略了db_列选项一样。你知道我怎样才能得到类似的结果吗
谢谢 来自Django文档的关于 ManyToManyField.db_table要创建用于存储的表的名称 多对多数据。如果没有提供,Django将假定 基于以下名称的默认名称:定义模型的表 字段本身的关系和名称
另外,根据原始数据库中的列名和非标准名称,您可能必须通过模型透视表定义为Django文档中关于 ManyToManyField.db_table要创建用于存储的表的名称 多对多数据。如果没有提供,Django将假定 基于以下名称的默认名称:定义模型的表 字段本身的关系和名称 此外,根据原始数据库中的列名和非标准名称,您可能必须通过模型透视表将其定义为表,您可以添加属性db_表 链接到上一个表,在您的案例中名为foo_old_table_name。 据文件说, 默认情况下,此表名是使用 “多对多”字段和所创建模型的表的名称 包含它 因此,对于字段new_m2m_field_name,创建链接的前一个表命名为:old_field_name_database_old_table_name。 因此: 选项through也可以更改,但是如果名称的修改是一致的,我认为没有必要这样做。您可以添加属性db\u表 链接到上一个表,在您的案例中名为foo_old_table_name。 据文件说, 默认情况下,此表名是使用 “多对多”字段和所创建模型的表的名称 包含它 因此,对于字段new_m2m_field_name,创建链接的前一个表命名为:old_field_name_database_old_table_name。 因此:
through选项也可以更改,但我认为如果对名称的修改是一致的,就没有必要了。您可能需要手动定义through模型,否则Django会在幕后隐式创建该模型,以使其不受管理
class Foo(models.Models):
new_m2m_field_name = models.ManyToManyField(
"RelatedModel",
blank=True,
db_column="old_m2m_field_name",
through="FooRelatedJoin", # <- new
)
class Meta:
managed = False
db_table = "foo_old_table_name"
class RelatedModel(models.Models):
name = models.CharField(max_length=50)
class Meta:
managed = False
db_table = "related_model_old_table_name"
class FooRelatedJoin(models.Models): # <- all new
foo = models.ForeignKey(Foo)
related_model = models.ForeignKey(RelatedModel)
class Meta:
managed = False
db_table = "foo_join_table"
您可能需要手动定义直通模型,否则Django会在幕后隐式创建该模型,以使其处于非托管状态
class Foo(models.Models):
new_m2m_field_name = models.ManyToManyField(
"RelatedModel",
blank=True,
db_column="old_m2m_field_name",
through="FooRelatedJoin", # <- new
)
class Meta:
managed = False
db_table = "foo_old_table_name"
class RelatedModel(models.Models):
name = models.CharField(max_length=50)
class Meta:
managed = False
db_table = "related_model_old_table_name"
class FooRelatedJoin(models.Models): # <- all new
foo = models.ForeignKey(Foo)
related_model = models.ForeignKey(RelatedModel)
class Meta:
managed = False
db_table = "foo_join_table"
对于多对多关系,表中没有列,只有附加的透视表,您了解这种ER建模的概念吗?感谢@iklinac,我想我了解,两个模型之间没有列,只有一个联接表,我想做的是告诉django,当我在一个Foo实例上调用新的_m2m_field_名称时,实际使用这个联接表。表中没有多对多关系的列,但有一个附加的透视表,您了解这种ER建模的概念吗?谢谢@iklinac,我想我了解,这两个模型之间没有列,只有一个联接表,我要做的是告诉django在调用Foo InstanceHanks上的新_m2m_field_名称时实际使用这个联接表。这正是我所需要的!这里不需要Foo模型中的db_列选项,这正是我需要的!这里不需要Foo模型中的db_列选项