我使用的是Django10、PostGres 3.9和Django3.2。我已经使用随附的多对多关系建立了这个模型...
class Account(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
...
crypto_currencies = models.ManyToManyField(CryptoCurrency)在生成并运行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我如何改变我的字段关系,或者生成一个迁移,使得级联关系是ON-DELETE级联?也就是说,当我删除一个帐户时,我希望该表中的伴随记录也被删除。
发布于 2021-11-30 04:11:35
仔细看看这个。我尝试复制您的模型,并且我还发现中间表没有级联。我没有回答你关于如何添加级联的主要问题,但似乎django做了级联行为,这已经支持它:
当我删除一个帐户时,我希望同时删除此表中的附带记录。
要演示,请执行以下操作:
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])如果您这样做了:
a.delete()Django运行以下SQL,模拟中间表上的级联:
[
{
'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'
}
]我在文档中找不到为什么它是这样做的。即使像这样添加自定义中介也会导致相同的行为:
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)发布于 2021-11-29 14:14:08
当您使用ManyToManyField时,Django会为您创建一个中间表,在本例中名为cbapp_account_crypto_currencies。您将来要做的是始终显式地创建中间模型AccountCryptoCurrencies,然后设置ManyToManyField的through属性。这将允许您将来向中介模型中添加更多字段。更多信息请点击这里: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)您现在需要生成一个迁移,但还没有应用它!通过将迁移包装在SeparateDatabaseAndState中来修改迁移。我还没有创建您的迁移文件,因为我没有完整的模型,但是您可以在这里查看如何创建迁移文件:How to add through option to existing ManyToManyField with migrations and data in django
现在可以应用迁移了,现在应该有了一个显式的中间表,而不会丢失数据。现在,您还可以向中间表添加其他字段并更改现有字段。您可以将on_delete=models.CASCADE添加到account字段并迁移更改。
https://stackoverflow.com/questions/70051103
复制相似问题