You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django 2.2迁移删除auth_permission行无效,求排查原因

问题原因及解决方案

这个现象的核心原因很明确:你的迁移确实执行了删除操作,但在整个migrate流程结束后,Django自动触发的权限重建机制又把你删掉的权限重新创建了回来,而ID更新正是因为这是全新生成的数据库记录。

为什么会这样?

Django在每次执行完所有迁移任务后,会发送post_migrate信号,而django.contrib.auth模块中的create_permissions函数会监听这个信号。它的作用是检查所有已注册模型的权限配置:如果发现某个模型对应的权限不存在(不管是被手动删除了还是从未创建过),就会自动重新生成这些权限。

你的迁移是在migrate过程中执行删除,但后续的post_migrate信号触发的操作,又把这些权限重新添加回了auth_permission表——这就是为什么你看到迁移显示[OK],但权限依然存在,甚至ID还变了。

而在shell_plus中删除时,并没有触发post_migrate信号,所以删除操作不会被后续的自动重建覆盖,自然能生效。

解决办法

根据你的实际场景,有两种常用的解决方案:

方案1:修改模型配置,阻止权限自动生成

如果这些权限是你在自定义模型的Meta类中声明的自定义权限,直接从模型配置里移除它们即可:

# 你的模型文件,比如models.py
from django.db import models

class YourModel(models.Model):
    # 模型字段...

    class Meta:
        # 移除不需要的权限声明
        permissions = [
            # 删掉 ('do_x', 'Can do X') 和 ('do_y', 'Can do Y')
            # 保留其他需要的权限
        ]

然后重新执行迁移,Django就不会再自动生成这些权限了,你之前的删除迁移也能彻底生效。

方案2:通过post_migrate信号在权限重建后删除

如果这些权限是Django为默认模型生成的(或者你无法修改模型配置),可以通过监听post_migrate信号,在权限自动重建完成后再执行一次删除操作:

  1. 在你的app的apps.py中添加信号处理逻辑:
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from django.contrib.auth.models import Permission
from django.db.models import Q

def remove_unwanted_permissions(sender, **kwargs):
    # 在权限重建完成后,删除指定权限
    Permission.objects.filter(Q(name='Can do X') | Q(name='Can do Y')).delete()

class AbcAppConfig(AppConfig):
    name = 'abc'

    def ready(self):
        # 绑定信号处理函数
        post_migrate.connect(remove_unwanted_permissions, sender=self)
  1. 在app的__init__.py中指定默认配置类:
default_app_config = 'abc.apps.AbcAppConfig'

这样每次migrate结束后,都会自动删除那些被Django重建的权限,确保最终的auth_permission表中没有这些记录。

内容的提问来源于stack exchange,提问作者zenprogrammer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 11:07:32