I'm using PostGres 10, Python 3.9, and Django 3.2. I have set up this model with the accompanying many-to-many relationship ...
class Account(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
...
crypto_currencies = models.ManyToManyField(CryptoCurrency)
After generating and running Django migrations, the following table was created ...
\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
How do I alter my field relation, or generate a migration, such that the cascade relationship is ON-DELETE CASCADE? That is, When I delete an account, I would like accompanying records in this table to also be deleted.
Had a closer look on this. I tried to replicate your models and I also see that the intermediary table has no cascade. I have no answer on your main question on how to add the cascade, but it seems that django does the cascade behavior which already supports this:
When I delete an account, I would like accompanying records in this table to also be deleted.
To demonstrate:
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])
If you do:
a.delete()
Django runs the following SQL which simulates the cascade on the intermediary table:
[
{
'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'
}
]
I can't find in the documentation why it is done this way though. Even adding a custom intermediary like this results in the same behavior:
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With