首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何为包含删除时级联的ManyToMany关系创建Django迁移?

如何为包含删除时级联的ManyToMany关系创建Django迁移?
EN

Stack Overflow用户
提问于 2021-11-21 01:10:32
回答 2查看 142关注 0票数 5

我使用的是Django10、PostGres 3.9和Django3.2。我已经使用随附的多对多关系建立了这个模型...

代码语言:javascript
复制
class Account(models.Model):    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...
    crypto_currencies = models.ManyToManyField(CryptoCurrency)

在生成并运行Django迁移之后,创建了下表...

代码语言:javascript
复制
\d cbapp_account_crypto_currencies;
                               Table "public.cbapp_account_crypto_currencies"
      Column       |  Type   |                                  Modifiers                                   
-------------------+---------+------------------------------------------------------------------------------
 id                | integer | not null default nextval('cbapp_account_crypto_currencies_id_seq'::regclass)
 account_id        | uuid    | not null
 cryptocurrency_id | uuid    | not null
Indexes:
    "cbapp_account_crypto_currencies_pkey" PRIMARY KEY, btree (id)
    "cbapp_account_crypto_cur_account_id_cryptocurrenc_38c41c43_uniq" UNIQUE CONSTRAINT, btree (account_id, cryptocurrency_id)
    "cbapp_account_crypto_currencies_account_id_611c9b45" btree (account_id)
    "cbapp_account_crypto_currencies_cryptocurrency_id_685fb811" btree (cryptocurrency_id)
Foreign-key constraints:
    "cbapp_account_crypto_account_id_611c9b45_fk_cbapp_acc" FOREIGN KEY (account_id) REFERENCES cbapp_account(id) DEFERRABLE INITIALLY DEFERRED
    "cbapp_account_crypto_cryptocurrency_id_685fb811_fk_cbapp_cry" FOREIGN KEY (cryptocurrency_id) REFERENCES cbapp_cryptocurrency(id) DEFERRABLE INITIALLY DEFERRED

我如何改变我的字段关系,或者生成一个迁移,使得级联关系是ON-DELETE级联?也就是说,当我删除一个帐户时,我希望该表中的伴随记录也被删除。

EN

回答 2

Stack Overflow用户

发布于 2021-11-30 04:11:35

仔细看看这个。我尝试复制您的模型,并且我还发现中间表没有级联。我没有回答你关于如何添加级联的主要问题,但似乎django做了级联行为,这已经支持它:

当我删除一个帐户时,我希望同时删除此表中的附带记录。

要演示,请执行以下操作:

代码语言:javascript
复制
a = Account.objects.create(name='test')
c1 = CryptoCurrency.objects.create(name='c1')
c2 = CryptoCurrency.objects.create(name='c2')
c3 = CryptoCurrency.objects.create(name='c3')
a.crypto_currencies.set([c1, c2, c3])

如果您这样做了:

代码语言:javascript
复制
a.delete()

Django运行以下SQL,模拟中间表上的级联:

代码语言:javascript
复制
[
    {
        'sql': 'DELETE FROM "myapp_account_crypto_currencies" WHERE "myapp_account_crypto_currencies"."account_id" IN (3)', 'time': '0.002'
    }, 
    {
        'sql': 'DELETE FROM "myapp_account" WHERE "myapp_account"."id" IN (3)', 'time': '0.001'
    }
]

我在文档中找不到为什么它是这样做的。即使像这样添加自定义中介也会导致相同的行为:

代码语言:javascript
复制
class Account(models.Model):
    name = models.CharField(max_length=100)
    crypto_currencies = models.ManyToManyField(CryptoCurrency, through='myapp.AccountCryptocurrencies')


class AccountCryptocurrencies(models.Model):
    account = models.ForeignKey(Account, on_delete=models.CASCADE)
    cryptocurrency = models.ForeignKey(CryptoCurrency, on_delete=models.CASCADE)
票数 1
EN

Stack Overflow用户

发布于 2021-11-29 14:14:08

当您使用ManyToManyField时,Django会为您创建一个中间表,在本例中名为cbapp_account_crypto_currencies。您将来要做的是始终显式地创建中间模型AccountCryptoCurrencies,然后设置ManyToManyFieldthrough属性。这将允许您将来向中介模型中添加更多字段。更多信息请点击这里:https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.ManyToManyField.through

您现在需要做的就是创建这个中间表:

代码语言:javascript
复制
class AccountCryptoCurrencies(models.Model):
    account = models.ForeignKey(Account)
    cryptocurrency = models.ForeignKey(CryptoCurrency)

    class Meta:
        db_table = 'cbapp_account_crypto_currencies'

class Account(models.Model):    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...
    crypto_currencies = models.ManyToManyField(CryptoCurrency, through=AccountCryptoCurrencies)

您现在需要生成一个迁移,但还没有应用它!通过将迁移包装在SeparateDatabaseAndState中来修改迁移。我还没有创建您的迁移文件,因为我没有完整的模型,但是您可以在这里查看如何创建迁移文件:How to add through option to existing ManyToManyField with migrations and data in django

现在可以应用迁移了,现在应该有了一个显式的中间表,而不会丢失数据。现在,您还可以向中间表添加其他字段并更改现有字段。您可以将on_delete=models.CASCADE添加到account字段并迁移更改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70051103

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档