【问题标题】:How to change the primary key of manytomany table in django如何在django中更改manytomany表的主键
【发布时间】:2021-02-04 06:47:51
【问题描述】:

我正在更改旧数据库的主键。我可以通过将 id 设置为主键来更改主键。

之前

class User(models.Model):
    name = models.CharField(max_length=5)
    email = models.CharField(max_length=5)
    age = models.CharField(max_length=5)

之后

class User(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.CharField(max_length=5)
    email = models.CharField(max_length=5)
    age = models.CharField(max_length=5)

然后

python manage.py makemigrations
python manage.py migrate

这工作正常。 但我也想更改通过 ManyToMany 字段创建的表的默认主键。

用户模型

class User(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.CharField(max_length=5)
    email = models.CharField(max_length=5)
    age = models.CharField(max_length=5)

用户档案模型

class UserProfile(models.Model):
    id = models.BigIntegerField(primary_key=True)
    address = models.CharField(max_length=5)
    father_name = models.CharField(max_length=5)
    pincode = models.CharField(max_length=5)
    user = models.ManyToManyField(User)

ManytoMany 字段创建名为 User_user_userprofile 的表,id 为 Autofield,基本上是以前的或默认的 django 主键。

id、user_id、userprofile_id ManytoMany Table

现在,如何更改由Django创建的ManytoMany Feild的primarykey ie id?

PS: 姜戈:1.11 蟒蛇:2.7.5 数据库:Sqlite3 3.7.17 2013-05-20

【问题讨论】:

    标签: django database django-models primary-key django-1.11


    【解决方案1】:

    我今天偶然发现了这个问题,并最终通过使用ManyToManyFieldthrough 参数解决了它。我为 Django v3.2.6 解决了它,但是 v1.11 的文档提到了相同参数的相同行为,因此希望该解决方案也适用于您的 Django 版本。这是 v1.11 文档的链接ManyToManyField.through

    through 参数允许您自己创建中间表(由ManyToManyField 自动创建)。您可以更好地控制中间表的外观、它应该具有哪些字段以及它们的行为应该是什么。希望你得到一张照片。

    让我举个例子,说明我遇到的问题以及我是如何解决的。希望这将使这一点更清楚。

    我试图在两个现有模型之间建立多对多关系。

    我的第一个模型是这样的,

    class BanglaWords(models.Model):
        class Meta:
            verbose_name_plural = 'Bangla Words'
    
        bng_id = models.CharField(max_length=16, primary_key=True)
        bangla_word = models.CharField(max_length=64)
    
        def __str__(self):
            return self.bangla_word
    

    第二个看起来像,

    class EnglishWords(models.Model):
        class Meta:
            verbose_name_plural = 'English Words'
    
        eng_id = models.IntegerField(primary_key=True)
        word = models.CharField(max_length=64)
        bangla_word = models.ManyToManyField(BanglaWords)
    
        def __str__(self):
            return self.word
    

    但这导致了一个中间表wordnet_englishwords_bangla_word,看起来像这样,

    wordnet_englishwords_bangla_word
    id
    englishwords_id
    banglawords_id

    但我不希望这样,我希望 bng_id 成为此表的 pk。我用ManyToManyField.through解决了如下问题,

    我自己定义了中间模型(表),并使用 through 参数,指向我创建的新中间模型并指示 django 按照我想要的方式创建表。

    首先我创建了中介模型,

    class BanglaEnglishRelations(models.Model):
        class Meta:
            verbose_name_plural = 'Bangla English Relations'
    
        bng_id = models.OneToOneField('BanglaWords', primary_key=True, on_delete=models.CASCADE)
        eng_id = models.ForeignKey('EnglishWords', on_delete=models.CASCADE)
    

    它将bng_id 定义为我想要的主键。

    其次,我告诉EnglishWords 中的ManyToManyField 将表格建立在BanglaEnglishRelations 之类的基础上,

    bangla_word = models.ManyToManyField(BanglaWords, through=BanglaEnglishRelations)
    

    这导致表格 wordnet_banglaenglishrelations 看起来像,

    wordnet_banglaenglishrelations
    bng_id_id
    eng_id_id

    并且完成了我的目的。您可以执行类似的操作来解决您的问题并将任何字段提升为 pk

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 2020-09-13
      • 1970-01-01
      • 1970-01-01
      • 2022-01-09
      • 2022-11-21
      • 2021-11-30
      相关资源
      最近更新 更多