Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用现有数据库覆盖Django中的M2M字段名和模型?_Python_Django_Postgresql_Django Rest Framework_Field - Fatal编程技术网

Python 如何使用现有数据库覆盖Django中的M2M字段名和模型?

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

我正在使用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
        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_列选项