update_permissions.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. # -*- coding: utf-8 -*-
  2. from django import VERSION as DJANGO_VERSION
  3. from django.apps import apps as django_apps
  4. from django.contrib.auth.management import create_permissions, _get_all_permissions
  5. from django.contrib.auth.models import Permission
  6. from django.contrib.contenttypes.models import ContentType
  7. from django.core.management.base import BaseCommand
  8. from django_extensions.management.utils import signalcommand
  9. class Command(BaseCommand):
  10. help = 'reloads permissions for specified apps, or all apps if no args are specified'
  11. def add_arguments(self, parser):
  12. super().add_arguments(parser)
  13. parser.add_argument('--apps', dest='apps', help='Reload permissions only for apps (comma separated)')
  14. parser.add_argument('--create-only', action='store_true', default=False, help='Only create missing permissions')
  15. parser.add_argument('--update-only', action='store_true', default=False, help='Only update permissions')
  16. @signalcommand
  17. def handle(self, *args, **options):
  18. if options['apps']:
  19. app_names = options['apps'].split(',')
  20. apps = [django_apps.get_app_config(x) for x in app_names]
  21. else:
  22. apps = django_apps.get_app_configs()
  23. if options['create_only']:
  24. do_create, do_update = True, False
  25. elif options['update_only']:
  26. do_create, do_update = False, True
  27. else:
  28. do_create, do_update = True, True
  29. for app in apps:
  30. if DJANGO_VERSION < (2, 2):
  31. # see https://github.com/django/django/commit/bec651a427fc032d9115d30c8c5d0e702d754f6c
  32. # Ensure that contenttypes are created for this app. Needed if
  33. # 'django.contrib.auth' is in INSTALLED_APPS before
  34. # 'django.contrib.contenttypes'.
  35. from django.contrib.contenttypes.management import create_contenttypes
  36. create_contenttypes(app, verbosity=options['verbosity'])
  37. if do_create:
  38. # create permissions if they do not exist
  39. create_permissions(app, options['verbosity'])
  40. if do_update:
  41. # update permission name's if changed
  42. for model in app.get_models():
  43. content_type = ContentType.objects.get_for_model(model)
  44. for codename, name in _get_all_permissions(model._meta):
  45. try:
  46. permission = Permission.objects.get(codename=codename, content_type=content_type)
  47. except Permission.DoesNotExist:
  48. continue
  49. if permission.name != name:
  50. old_str = str(permission)
  51. permission.name = name
  52. if options['verbosity'] >= 2:
  53. self.stdout.write(self.style.SUCCESS("Update permission '%s' to '%s'" % (old_str, permission)))
  54. permission.save()