You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

158 lines
6.5 KiB

"""
Management command برای migration داده‌های موجود به سیستم نقش‌های چندگانه
"""
from django.core.management.base import BaseCommand
from django.contrib.auth.models import Group
from apps.account.models import User
from apps.course.models import Course, Participant
class Command(BaseCommand):
help = 'Migrate existing user data to multiple roles system'
def add_arguments(self, parser):
parser.add_argument(
'--dry-run',
action='store_true',
help='Show what would be done without making changes',
)
def handle(self, *args, **options):
dry_run = options['dry_run']
if dry_run:
self.stdout.write(
self.style.WARNING('DRY RUN MODE - No changes will be made')
)
# اطمینان از وجود گروه‌ها
self.ensure_groups_exist(dry_run)
# Migration کاربران بر اساس user_type فعلی
self.migrate_user_types(dry_run)
# Migration کاربرانی که هم استاد و هم دانش‌آموز هستند
self.migrate_professor_students(dry_run)
self.stdout.write(
self.style.SUCCESS('Migration completed successfully!')
)
def ensure_groups_exist(self, dry_run):
"""اطمینان از وجود گروه‌های مورد نیاز"""
groups = [
"Professor Group",
"Student Group",
"Client Group",
"Admin Group",
"Super Admin Group"
]
for group_name in groups:
if dry_run:
exists = Group.objects.filter(name=group_name).exists()
if not exists:
self.stdout.write(f'Would create group: {group_name}')
else:
group, created = Group.objects.get_or_create(name=group_name)
if created:
self.stdout.write(f'Created group: {group_name}')
def migrate_user_types(self, dry_run):
"""Migration کاربران بر اساس user_type فعلی"""
users = User.objects.all()
for user in users:
# چک کنیم که آیا کاربر قبلاً در گروه مناسب است یا خیر
expected_group_name = f"{user.user_type.capitalize()} Group"
if not user.groups.filter(name=expected_group_name).exists():
if dry_run:
self.stdout.write(
f'Would add user {user.email} to group {expected_group_name}'
)
else:
try:
group = Group.objects.get(name=expected_group_name)
user.groups.add(group)
self.stdout.write(
f'Added user {user.email} to group {expected_group_name}'
)
except Group.DoesNotExist:
self.stdout.write(
self.style.ERROR(f'Group {expected_group_name} does not exist')
)
def migrate_professor_students(self, dry_run):
"""شناسایی و migration کاربرانی که هم استاد و هم دانش‌آموز هستند"""
# کاربرانی که دوره ساخته‌اند (استاد هستند)
professors = User.objects.filter(courses__isnull=False).distinct()
# کاربرانی که در دوره شرکت کرده‌اند (دانش‌آموز هستند)
students = User.objects.filter(participated_courses__isnull=False).distinct()
# کاربرانی که هم استاد و هم دانش‌آموز هستند
professor_students = professors.filter(
id__in=students.values_list('id', flat=True)
)
self.stdout.write(
f'Found {professor_students.count()} users who are both professors and students'
)
for user in professor_students:
# اطمینان از اینکه در هر دو گروه هستند
professor_group_exists = user.groups.filter(name="Professor Group").exists()
student_group_exists = user.groups.filter(name="Student Group").exists()
if not professor_group_exists:
if dry_run:
self.stdout.write(
f'Would add professor role to user {user.email}'
)
else:
user.add_role('professor')
self.stdout.write(
f'Added professor role to user {user.email}'
)
if not student_group_exists:
if dry_run:
self.stdout.write(
f'Would add student role to user {user.email}'
)
else:
user.add_role('student')
self.stdout.write(
f'Added student role to user {user.email}'
)
# نمایش آمار
courses_taught = Course.objects.filter(professor=user).count()
courses_enrolled = Participant.objects.filter(student=user).count()
self.stdout.write(
f' User {user.email}: teaches {courses_taught} courses, '
f'enrolled in {courses_enrolled} courses'
)
def get_user_statistics(self):
"""نمایش آمار کاربران"""
total_users = User.objects.count()
professors = User.objects.filter(groups__name="Professor Group").count()
students = User.objects.filter(groups__name="Student Group").count()
clients = User.objects.filter(groups__name="Client Group").count()
# کاربرانی که چندین نقش دارند
multi_role_users = User.objects.filter(
groups__name__in=["Professor Group", "Student Group"]
).annotate(
role_count=models.Count('groups')
).filter(role_count__gt=1).count()
self.stdout.write('\n--- User Statistics ---')
self.stdout.write(f'Total users: {total_users}')
self.stdout.write(f'Professors: {professors}')
self.stdout.write(f'Students: {students}')
self.stdout.write(f'Clients: {clients}')
self.stdout.write(f'Multi-role users: {multi_role_users}')