[英]Why doesn't my model's “on_delete=models.CASCADE,” generate a cascading foreign key constraint?
I am using Django, Python 3.7, and PostgreSQL 9.5. 我正在使用Django,Python 3.7和PostgreSQL 9.5。 How do I mark up my model such taht a cascading foreign key constraint gets generated?
如何标记我的模型,以便生成级联外键约束? I currently have this in my models.py file ...
我目前在models.py文件中有这个...
class ArticleStat(models.Model):
article = models.ForeignKey(Article, on_delete=models.CASCADE, )
When I run make migrations my_project
in the management console, it produces a file that contains this ... 当我在管理控制台中运行
make migrations my_project
时,它会生成一个包含此文件的文件...
migrations.CreateModel(
name='ArticleStat',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
...
('article', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='my_project.Article')),
],
),
However, when I run the migration (using migrate my_project 0001
), the resulting foreign key does not contain a cascade delete constraint. 但是,当我运行迁移(使用
migrate my_project 0001
)时,生成的外键不包含级联删除约束。 This is what the description looks like in PostgreSQL ... 这就是PostgreSQL中的描述......
"my_project_articlesta_article_id_a02a5add_fk_my_project" FOREIGN KEY (article_id) REFERENCES my_project_article(id) DEFERRABLE INITIALLY DEFERRED
How else can I get my models.py file to output a cascading delete foreign key constraint? 我怎么能得到我的models.py文件输出级联删除外键约束?
As described in the django documentation of ForeignKey
django merely emulates this behaviour instead of deferring it to the database. 如
ForeignKey
django的django文档中所述仅仅模拟此行为而不是将其推迟到数据库。
Django emulates the behavior of the SQL constraint ON DELETE CASCADE and also deletes the object containing the ForeignKey.
Django模拟SQL约束ON DELETE CASCADE的行为,并删除包含ForeignKey的对象。
So to answer your question: This is expected behavior and will still work just like you would expect it to work on the database level. 所以回答你的问题:这是预期的行为,并且仍然会像你期望它在数据库级别上工作一样工作。
How else can I get my models.py file to output a cascading delete foreign key constraint?
我怎么能得到我的models.py文件输出级联删除外键约束?
You can't as django currently does not support this feature. 您不能因为django目前不支持此功能。 However there is a ticket discussing to add it: https://code.djangoproject.com/ticket/21961
但是有一张票要讨论添加它: https : //code.djangoproject.com/ticket/21961
While I highly recommend to just let django handle this for you there might be reasons not to do so. 虽然我强烈建议让django为你处理这个,但可能有理由不这样做。
To opt out of database table creation or deletion operations you can set Options.managed to False
in the Meta
class of ArticleStat
. 要退出数据库表创建或删除操作,可以在
ArticleStat
的Meta
类中将Options.managed设置为False
。 That would however also mean that you are now responsible to do the migrations manually eg writing the CREATE TABLE
statement to define the table including the foreign key constraint (which you thus have full control over now). 但这也意味着您现在负责手动执行迁移,例如编写
CREATE TABLE
语句来定义包含外键约束的表(因此您可以完全控制它)。 Another consideration to take into account is that you should instruct django to not do anything on deletion of a referenced Article
object anymore (as your database is now responsible for that). 要考虑的另一个考虑因素是,您应该指示django不再对删除引用的
Article
对象做任何事情(因为您的数据库现在对此负责)。 That can be ensured by setting on_delete
to models.DO_NOTHING . 通过将
on_delete
设置为models.DO_NOTHING可以确保这一点 。
Put together your ArticleStat
would now look like this: 将
ArticleStat
放在一起现在看起来像这样:
class ArticleStat(models.Model):
article = models.ForeignKey(Article, on_delete=models.DO_NOTHING)
class Meta:
managed = False
opting out means opting out of django signals as well. 选择退出意味着选择退出django信号。 In particular
pre_delete
and post_delete
won't be fired for cascaded objects anymore. 特别是不再为级联对象触发
pre_delete
和post_delete
。
As mentioned in the ticket description mixing database- and django-cascading won't play nicely together. 正如票证说明中所提到的,混合数据库和django-cascading不能很好地融合在一起。
If a model A references a model B using CASCADE_DB, but model B references model C using regular CASCADE, a deletion of A won't cascade all the way to C.
如果模型A使用CASCADE_DB引用模型B,但模型B使用常规CASCADE引用模型C,则删除A将不会一直级联到C.
That being said I couldn't find any definite proof of why django is handling this the way it does currently. 话虽如此,我找不到任何明确的证据,说明为什么django正在以目前的方式处理它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.