utils.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import datetime
  2. import json
  3. try:
  4. from django.apps.registry import apps
  5. except ImportError:
  6. try:
  7. from django.apps import apps # Fix Django 1.7 import issue
  8. except ImportError:
  9. pass
  10. from django.core.serializers.json import DjangoJSONEncoder
  11. from django.http import HttpResponse
  12. from django.core.urlresolvers import reverse, resolve, NoReverseMatch
  13. from django.contrib import admin
  14. from django.contrib.admin import AdminSite
  15. from django.utils.encoding import smart_text
  16. from django.utils.text import capfirst
  17. from django.contrib import messages
  18. from django.utils.encoding import force_text
  19. from django.utils.functional import Promise
  20. class JsonResponse(HttpResponse):
  21. """
  22. An HTTP response class that consumes data to be serialized to JSON.
  23. :param data: Data to be dumped into json. By default only ``dict`` objects
  24. are allowed to be passed due to a security flaw before EcmaScript 5. See
  25. the ``safe`` parameter for more information.
  26. :param encoder: Should be an json encoder class. Defaults to
  27. ``django.core.serializers.json.DjangoJSONEncoder``.
  28. :param safe: Controls if only ``dict`` objects may be serialized. Defaults
  29. to ``True``.
  30. """
  31. def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, **kwargs):
  32. if safe and not isinstance(data, dict):
  33. raise TypeError('In order to allow non-dict objects to be '
  34. 'serialized set the safe parameter to False')
  35. kwargs.setdefault('content_type', 'application/json')
  36. data = json.dumps(data, cls=encoder)
  37. super(JsonResponse, self).__init__(content=data, **kwargs)
  38. def get_app_list(context, order=True):
  39. admin_site = get_admin_site(context.get('current_app', ''))
  40. request = context['request']
  41. app_dict = {}
  42. for model, model_admin in admin_site._registry.items():
  43. app_label = model._meta.app_label
  44. try:
  45. has_module_perms = model_admin.has_module_permission(request)
  46. except AttributeError:
  47. has_module_perms = request.user.has_module_perms(app_label) # Fix Django < 1.8 issue
  48. if has_module_perms:
  49. perms = model_admin.get_model_perms(request)
  50. # Check whether user has any perm for this module.
  51. # If so, add the module to the model_list.
  52. if True in perms.values():
  53. info = (app_label, model._meta.model_name)
  54. model_dict = {
  55. 'name': capfirst(model._meta.verbose_name_plural),
  56. 'object_name': model._meta.object_name,
  57. 'perms': perms,
  58. }
  59. if perms.get('change', False):
  60. try:
  61. model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=admin_site.name)
  62. except NoReverseMatch:
  63. pass
  64. if perms.get('add', False):
  65. try:
  66. model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=admin_site.name)
  67. except NoReverseMatch:
  68. pass
  69. if app_label in app_dict:
  70. app_dict[app_label]['models'].append(model_dict)
  71. else:
  72. try:
  73. name = apps.get_app_config(app_label).verbose_name
  74. except NameError:
  75. name = app_label.title()
  76. app_dict[app_label] = {
  77. 'name': name,
  78. 'app_label': app_label,
  79. 'app_url': reverse(
  80. 'admin:app_list',
  81. kwargs={'app_label': app_label},
  82. current_app=admin_site.name,
  83. ),
  84. 'has_module_perms': has_module_perms,
  85. 'models': [model_dict],
  86. }
  87. # Sort the apps alphabetically.
  88. app_list = list(app_dict.values())
  89. if order:
  90. app_list.sort(key=lambda x: x['name'].lower())
  91. # Sort the models alphabetically within each app.
  92. for app in app_list:
  93. app['models'].sort(key=lambda x: x['name'])
  94. return app_list
  95. def get_admin_site(current_app):
  96. try:
  97. resolver_match = resolve(reverse('%s:index' % current_app))
  98. for func_closure in resolver_match.func.func_closure:
  99. if isinstance(func_closure.cell_contents, AdminSite):
  100. return func_closure.cell_contents
  101. except:
  102. pass
  103. return admin.site
  104. def get_admin_site_name(context):
  105. return get_admin_site(context).name
  106. class LazyDateTimeEncoder(json.JSONEncoder):
  107. def default(self, obj):
  108. if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date):
  109. return obj.isoformat()
  110. elif isinstance(obj, Promise):
  111. return force_text(obj)
  112. return self.encode(obj)
  113. def get_model_instance_label(instance):
  114. if getattr(instance, "related_label", None):
  115. return instance.related_label()
  116. return smart_text(instance)
  117. class SuccessMessageMixin(object):
  118. """
  119. Adds a success message on successful form submission.
  120. """
  121. success_message = ''
  122. def form_valid(self, form):
  123. response = super(SuccessMessageMixin, self).form_valid(form)
  124. success_message = self.get_success_message(form.cleaned_data)
  125. if success_message:
  126. messages.success(self.request, success_message)
  127. return response
  128. def get_success_message(self, cleaned_data):
  129. return self.success_message % cleaned_data