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

Dav*_*ave 5 django postgresql many-to-many cascade python-3.x

我使用的是 PostGres 10、Python 3.9 和 Django 3.2。我已经建立了这个模型以及伴随的多对多关系......

class Account(models.Model):    
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    ...
    crypto_currencies = models.ManyToManyField(CryptoCurrency)
Run Code Online (Sandbox Code Playgroud)

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

\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
Run Code Online (Sandbox Code Playgroud)

如何更改我的字段关系或生成迁移,以便级联关系为 ON-DELETE CASCADE?也就是说,当我删除帐户时,我希望该表中的附带记录也被删除。

Tai*_*Rex 0

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

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

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)
Run Code Online (Sandbox Code Playgroud)

您现在需要生成迁移,但暂时不要应用它!通过将迁移包装在SeparateDatabaseAndState. 我还没有创建您的迁移文件,因为我没有完整的模型,但您可以在此处查看如何执行此操作:How to add through option to existing ManyToManyField with Migrations and data in django

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