from django.core.management.base import BaseCommand from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType class Command(BaseCommand): help = 'Renames permissions to be more user-friendly' def handle(self, *args, **options): # Dictionary mapping (app_label, model_name, codename) -> New Name # Or just (codename) -> New Name if unique enough, but (app, model) is safer. # We can also map just the model's permissions generically if we want. renames = { # Core App - Business Logic ('core', 'project', 'add_project'): 'Manage: Create New Project', ('core', 'project', 'change_project'): 'Manage: Edit Project Details', ('core', 'project', 'delete_project'): 'Manage: Delete Project', ('core', 'project', 'view_project'): 'Manage: View Projects (Dashboard Access)', ('core', 'worker', 'add_worker'): 'Manage: Add New Worker', ('core', 'worker', 'change_worker'): 'Manage: Edit Worker Details', ('core', 'worker', 'delete_worker'): 'Manage: Delete Worker', ('core', 'worker', 'view_worker'): 'Manage: View Worker Profiles', ('core', 'team', 'add_team'): 'Manage: Create Team', ('core', 'team', 'change_team'): 'Manage: Edit Team Structure', ('core', 'team', 'delete_team'): 'Manage: Delete Team', ('core', 'team', 'view_team'): 'Manage: View Teams', ('core', 'worklog', 'add_worklog'): 'Log Work: Add Attendance Entry', ('core', 'worklog', 'change_worklog'): 'Log Work: Edit Attendance Entry', ('core', 'worklog', 'delete_worklog'): 'Log Work: Delete Attendance Entry', ('core', 'worklog', 'view_worklog'): 'Log Work: View Attendance History', ('core', 'payrollrecord', 'add_payrollrecord'): 'Payroll: Generate Payment Record', ('core', 'payrollrecord', 'change_payrollrecord'): 'Payroll: Edit Payment Record', ('core', 'payrollrecord', 'delete_payrollrecord'): 'Payroll: Delete Payment Record', ('core', 'payrollrecord', 'view_payrollrecord'): 'Payroll: View Payment History', ('core', 'loan', 'add_loan'): 'Loans: Create New Loan', ('core', 'loan', 'change_loan'): 'Loans: Edit Loan Details', ('core', 'loan', 'delete_loan'): 'Loans: Delete Loan', ('core', 'loan', 'view_loan'): 'Loans: View Loan Registry', ('core', 'expensereceipt', 'add_expensereceipt'): 'Receipts: Add Expense Receipt', ('core', 'expensereceipt', 'change_expensereceipt'): 'Receipts: Edit Expense Receipt', ('core', 'expensereceipt', 'delete_expensereceipt'): 'Receipts: Delete Expense Receipt', ('core', 'expensereceipt', 'view_expensereceipt'): 'Receipts: View Expense History', # Auth App ('auth', 'user', 'add_user'): 'Admin: Create User Accounts', ('auth', 'user', 'change_user'): 'Admin: Edit User Accounts', ('auth', 'user', 'delete_user'): 'Admin: Delete User Accounts', ('auth', 'user', 'view_user'): 'Admin: View User Accounts', ('auth', 'group', 'add_group'): 'Admin: Create Permission Groups', ('auth', 'group', 'change_group'): 'Admin: Edit Permission Groups', ('auth', 'group', 'delete_group'): 'Admin: Delete Permission Groups', ('auth', 'group', 'view_group'): 'Admin: View Permission Groups', # System / Technical (Marking as Technical to help user ignore them) ('sessions', 'session', 'add_session'): 'System (Tech): Add Session', ('sessions', 'session', 'change_session'): 'System (Tech): Manage Sessions', ('sessions', 'session', 'delete_session'): 'System (Tech): Clear Sessions', ('sessions', 'session', 'view_session'): 'System (Tech): View Sessions', ('admin', 'logentry', 'add_logentry'): 'System (Tech): Add Admin Log', ('admin', 'logentry', 'change_logentry'): 'System (Tech): Edit Admin Log', ('admin', 'logentry', 'delete_logentry'): 'System (Tech): Clear Admin Log', ('admin', 'logentry', 'view_logentry'): 'System (Tech): View Admin Log', ('contenttypes', 'contenttype', 'add_contenttype'): 'System (Tech): Add Content Type', ('contenttypes', 'contenttype', 'change_contenttype'): 'System (Tech): Edit Content Type', ('contenttypes', 'contenttype', 'delete_contenttype'): 'System (Tech): Delete Content Type', ('contenttypes', 'contenttype', 'view_contenttype'): 'System (Tech): View Content Types', } count = 0 for (app_label, model, codename), new_name in renames.items(): try: # We need to find the content type first to be safe, or filter by codename + content_type__app_label # but direct filter is easiest if unique. # However, codenames can be shared across models (though rare for standard CRUD). # Safer to lookup ContentType. ct = ContentType.objects.filter(app_label=app_label, model=model).first() if not ct: self.stdout.write(self.style.WARNING(f"Model {app_label}.{model} not found, skipping.")) continue perm = Permission.objects.filter(content_type=ct, codename=codename).first() if perm: perm.name = new_name perm.save() self.stdout.write(f"Renamed {codename} -> {new_name}") count += 1 else: self.stdout.write(self.style.WARNING(f"Permission {codename} for {app_label}.{model} not found.")) except Exception as e: self.stdout.write(self.style.ERROR(f"Error renaming {codename}: {e}")) self.stdout.write(self.style.SUCCESS(f"Successfully updated {count} permission names."))