是否可以将m2m对象设置为与自身没有递归关系?

2024-10-01 00:26:29 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我有一个与自身有m2msubscribers关系的用户模型

这个想法是用户不能自己订阅

有没有可能在模型级别处理这个问题


Tags: 用户模型关系级别m2msubscribers
2条回答

您可以使用带有“pre_add”操作的m2m_changed信号来验证添加对象See docs

假设这对您的设计是一个很强的约束,我会让数据库知道并在数据库本身上实施它。相应的SQL如下所示:

ALTER TABLE "myapp_subscribers" ADD CONSTRAINT "myapp_subscribers_not_self" CHECK (user1_id <> user2_id)

user1_iduser2_id替换为实际的字段名,myapp_替换为应用程序的实际名称,not_self替换为您想赋予约束的任何名称,只要它的目的对您来说是显而易见的,就无所谓了

虽然Django没有为这类事情提供自动化,但是自己编写一个定制的迁移步骤是相当容易的。如果要创建新的应用程序,请在Django生成的迁移文件中,将此添加到迁移步骤列表的末尾:

migrations.RunSQL(
    [('ALTER TABLE "myapp_subscribers" ADD CONSTRAINT "myapp_subscribers_not_self" CHECK (user1_id <> user2_id);', None)],
    [('ALTER TABLE "myapp_subscribers" DROP CONSTRAINT "myapp_subscribers_not_self";', None)]
)

第二个SQL行允许反转操作。如果忽略它,Django将拒绝向后运行迁移

如果要更改现有应用程序,请将其包含在正在创建的迁移中,或者创建一个空迁移

./manage.py makemigrations  empty myapp

添加约束后,数据库将强制执行该约束,并阻止任何尝试(无论是来自django还是其他任何东西)将用户订阅给他自己

在Django方面,这意味着任何这样做的尝试都会引起^{}。如果在transaction中,这也会导致事务完全回滚

相关问题 更多 >