Consider the following models.py
:
from django.db import models
class Foo(models.Model):
bars = models.ManyToManyField(
"Bar",
blank=True
)
class Bar(models.Model):
foos = models.ManyToManyField(
"Foo",
blank=True,
through="Foo_bars"
)
and the associated migration:
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = []
operations = [
migrations.CreateModel(
name="Bar",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
],
),
migrations.CreateModel(
name="Foo",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("bars", models.ManyToManyField(blank=True, to="demo.bar")),
],
),
migrations.AddField(
model_name="bar",
name="foos",
field=models.ManyToManyField(blank=True, to="demo.foo"),
),
]
Running
python manage.py migrate && python manage.py flush --no-input --traceback
produces the following trace back
File "/opt/venv/lib/python3.13/site-packages/psycopg/cursor.py", line 97, in execute
raise ex.with_traceback(None)
django.db.utils.NotSupportedError: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "demo_bar_foos" references "demo_foo".
HINT: Truncate table "demo_bar_foos" at the same time, or use TRUNCATE ... CASCADE.
How can I fix this problem? How can I add cascade?
A full reproducible example is available at https://github.com/rgaiacs/django-flush-problem.
This is not how you define ManyToManyField
s. If you define a ManyToManyField
in one of the models, you can access it in the other direction because of the foo_bars
, so:
from django.db import models
class Foo(models.Model):
bars = models.ManyToManyField('Bar', blank=True, related_name='foos')
class Bar(models.Model):
# foos = models.ManyToManyField(
# "Foo",
# blank=True,
# through="Foo_bars"
# )
pass
It thus allows to work with my_bar.foos.all()
because of the related_name=...
[Django-doc].