144 lines
4.7 KiB
Python
144 lines
4.7 KiB
Python
"""
|
||
删除用户脚本(保留超级管理员admin)
|
||
使用方法: python manage.py delete_users_except_admin
|
||
"""
|
||
|
||
from django.core.management.base import BaseCommand
|
||
from django.db import models
|
||
from User.models import User
|
||
|
||
|
||
class Command(BaseCommand):
|
||
help = '删除所有用户(保留超级管理员admin)'
|
||
|
||
def add_arguments(self, parser):
|
||
parser.add_argument(
|
||
'--dry-run',
|
||
action='store_true',
|
||
help='仅显示将要删除的用户,不实际删除',
|
||
)
|
||
parser.add_argument(
|
||
'--hard-delete',
|
||
action='store_true',
|
||
help='硬删除(物理删除),默认是软删除(设置is_deleted=True)',
|
||
)
|
||
parser.add_argument(
|
||
'--confirm',
|
||
action='store_true',
|
||
help='跳过确认提示,直接执行删除',
|
||
)
|
||
|
||
def handle(self, *args, **options):
|
||
dry_run = options['dry_run']
|
||
hard_delete = options['hard_delete']
|
||
confirm = options['confirm']
|
||
|
||
# 查询所有未删除的用户,排除admin
|
||
users_to_delete = User.objects.filter(
|
||
is_deleted=False
|
||
).exclude(
|
||
username='admin'
|
||
).exclude(
|
||
account='admin'
|
||
)
|
||
|
||
total_count = users_to_delete.count()
|
||
|
||
if total_count == 0:
|
||
self.stdout.write(
|
||
self.style.SUCCESS('没有需要删除的用户(除了admin)')
|
||
)
|
||
return
|
||
|
||
# 显示将要删除的用户信息
|
||
self.stdout.write(
|
||
self.style.WARNING(f'\n找到 {total_count} 个用户需要删除(排除admin):')
|
||
)
|
||
self.stdout.write('-' * 80)
|
||
|
||
for user in users_to_delete[:20]: # 只显示前20个
|
||
self.stdout.write(
|
||
f' ID: {user.id}, 用户名: {user.username}, 账号: {user.account}, '
|
||
f'状态: {user.state}, 团队: {user.team}'
|
||
)
|
||
|
||
if total_count > 20:
|
||
self.stdout.write(f' ... 还有 {total_count - 20} 个用户')
|
||
|
||
if dry_run:
|
||
self.stdout.write(
|
||
self.style.SUCCESS('\n[模拟运行] 以上用户将被删除(实际未删除)')
|
||
)
|
||
return
|
||
|
||
# 确认删除
|
||
if not confirm:
|
||
self.stdout.write(
|
||
self.style.WARNING(
|
||
f'\n警告:将删除 {total_count} 个用户(保留admin用户)'
|
||
)
|
||
)
|
||
response = input('确认删除?输入 "yes" 继续: ')
|
||
if response.lower() != 'yes':
|
||
self.stdout.write(self.style.ERROR('操作已取消'))
|
||
return
|
||
|
||
# 执行删除
|
||
deleted_count = 0
|
||
failed_count = 0
|
||
|
||
self.stdout.write('\n开始删除用户...')
|
||
|
||
for user in users_to_delete:
|
||
try:
|
||
if hard_delete:
|
||
# 硬删除(物理删除)
|
||
user.delete()
|
||
self.stdout.write(
|
||
f' ✓ 硬删除用户: {user.username} (ID: {user.id})'
|
||
)
|
||
else:
|
||
# 软删除(设置is_deleted=True)
|
||
user.is_deleted = True
|
||
user.save(update_fields=['is_deleted'])
|
||
self.stdout.write(
|
||
f' ✓ 软删除用户: {user.username} (ID: {user.id})'
|
||
)
|
||
deleted_count += 1
|
||
except Exception as e:
|
||
self.stdout.write(
|
||
self.style.ERROR(
|
||
f' ✗ 删除用户失败: {user.username} (ID: {user.id}) - {str(e)}'
|
||
)
|
||
)
|
||
failed_count += 1
|
||
|
||
# 显示结果
|
||
self.stdout.write('\n' + '=' * 80)
|
||
self.stdout.write(
|
||
self.style.SUCCESS(
|
||
f'删除完成!成功: {deleted_count}, 失败: {failed_count}, 总计: {total_count}'
|
||
)
|
||
)
|
||
|
||
if hard_delete:
|
||
self.stdout.write(self.style.WARNING('注意:已执行硬删除(物理删除)'))
|
||
else:
|
||
self.stdout.write(self.style.SUCCESS('已执行软删除(is_deleted=True)'))
|
||
|
||
# 验证admin用户是否还在
|
||
admin_users = User.objects.filter(
|
||
is_deleted=False
|
||
).filter(
|
||
models.Q(username='admin') | models.Q(account='admin')
|
||
)
|
||
|
||
if admin_users.exists():
|
||
self.stdout.write(
|
||
self.style.SUCCESS(f'✓ 超级管理员admin用户已保留(共 {admin_users.count()} 个)')
|
||
)
|
||
else:
|
||
self.stdout.write(
|
||
self.style.ERROR('⚠ 警告:未找到admin用户!')
|
||
)
|