utils.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import datetime
  2. import json
  3. from django.utils import translation
  4. try:
  5. from django.apps.registry import apps
  6. except ImportError:
  7. try:
  8. from django.apps import apps # Fix Django 1.7 import issue
  9. except ImportError:
  10. pass
  11. from django.core.serializers.json import DjangoJSONEncoder
  12. from django.http import HttpResponse
  13. from django.core.urlresolvers import reverse, resolve, NoReverseMatch
  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. from django.contrib.admin.options import IncorrectLookupParameters
  21. from django.core import urlresolvers
  22. from django.contrib import admin
  23. class JsonResponse(HttpResponse):
  24. """
  25. An HTTP response class that consumes data to be serialized to JSON.
  26. :param data: Data to be dumped into json. By default only ``dict`` objects
  27. are allowed to be passed due to a security flaw before EcmaScript 5. See
  28. the ``safe`` parameter for more information.
  29. :param encoder: Should be an json encoder class. Defaults to
  30. ``django.core.serializers.json.DjangoJSONEncoder``.
  31. :param safe: Controls if only ``dict`` objects may be serialized. Defaults
  32. to ``True``.
  33. """
  34. def __init__(self, data, encoder=DjangoJSONEncoder, safe=True, **kwargs):
  35. if safe and not isinstance(data, dict):
  36. raise TypeError('In order to allow non-dict objects to be '
  37. 'serialized set the safe parameter to False')
  38. kwargs.setdefault('content_type', 'application/json')
  39. data = json.dumps(data, cls=encoder)
  40. super(JsonResponse, self).__init__(content=data, **kwargs)
  41. def get_app_list(context, order=True):
  42. admin_site = get_admin_site(context)
  43. request = context['request']
  44. app_dict = {}
  45. for model, model_admin in admin_site._registry.items():
  46. app_label = model._meta.app_label
  47. try:
  48. has_module_perms = model_admin.has_module_permission(request)
  49. except AttributeError:
  50. has_module_perms = request.user.has_module_perms(app_label) # Fix Django < 1.8 issue
  51. if has_module_perms:
  52. perms = model_admin.get_model_perms(request)
  53. # Check whether user has any perm for this module.
  54. # If so, add the module to the model_list.
  55. if True in perms.values():
  56. info = (app_label, model._meta.model_name)
  57. model_dict = {
  58. 'name': capfirst(model._meta.verbose_name_plural),
  59. 'object_name': model._meta.object_name,
  60. 'perms': perms,
  61. }
  62. if perms.get('change', False):
  63. try:
  64. model_dict['admin_url'] = reverse('admin:%s_%s_changelist' % info, current_app=admin_site.name)
  65. except NoReverseMatch:
  66. pass
  67. if perms.get('add', False):
  68. try:
  69. model_dict['add_url'] = reverse('admin:%s_%s_add' % info, current_app=admin_site.name)
  70. except NoReverseMatch:
  71. pass
  72. if app_label in app_dict:
  73. app_dict[app_label]['models'].append(model_dict)
  74. else:
  75. try:
  76. name = apps.get_app_config(app_label).verbose_name
  77. except NameError:
  78. name = app_label.title()
  79. app_dict[app_label] = {
  80. 'name': name,
  81. 'app_label': app_label,
  82. 'app_url': reverse(
  83. 'admin:app_list',
  84. kwargs={'app_label': app_label},
  85. current_app=admin_site.name,
  86. ),
  87. 'has_module_perms': has_module_perms,
  88. 'models': [model_dict],
  89. }
  90. # Sort the apps alphabetically.
  91. app_list = list(app_dict.values())
  92. if order:
  93. app_list.sort(key=lambda x: x['name'].lower())
  94. # Sort the models alphabetically within each app.
  95. for app in app_list:
  96. app['models'].sort(key=lambda x: x['name'])
  97. return app_list
  98. def get_admin_site(context):
  99. try:
  100. current_resolver = resolve(context.get('request').path)
  101. index_resolver = resolve(reverse('%s:index' % current_resolver.namespaces[0]))
  102. if hasattr(index_resolver.func, 'admin_site'):
  103. return index_resolver.func.admin_site
  104. for func_closure in index_resolver.func.__closure__:
  105. if isinstance(func_closure.cell_contents, AdminSite):
  106. return func_closure.cell_contents
  107. except:
  108. pass
  109. return admin.site
  110. def get_admin_site_name(context):
  111. return get_admin_site(context).name
  112. class LazyDateTimeEncoder(json.JSONEncoder):
  113. def default(self, obj):
  114. if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date):
  115. return obj.isoformat()
  116. elif isinstance(obj, Promise):
  117. return force_text(obj)
  118. return self.encode(obj)
  119. def get_model_instance_label(instance):
  120. if getattr(instance, "related_label", None):
  121. return instance.related_label()
  122. return smart_text(instance)
  123. class SuccessMessageMixin(object):
  124. """
  125. Adds a success message on successful form submission.
  126. """
  127. success_message = ''
  128. def form_valid(self, form):
  129. response = super(SuccessMessageMixin, self).form_valid(form)
  130. success_message = self.get_success_message(form.cleaned_data)
  131. if success_message:
  132. messages.success(self.request, success_message)
  133. return response
  134. def get_success_message(self, cleaned_data):
  135. return self.success_message % cleaned_data
  136. def get_model_queryset(admin_site, model, request, preserved_filters=None):
  137. model_admin = admin_site._registry.get(model)
  138. try:
  139. changelist_url = urlresolvers.reverse('%s:%s_%s_changelist' % (
  140. admin_site.name,
  141. model._meta.app_label,
  142. model._meta.model_name
  143. ))
  144. except NoReverseMatch:
  145. return
  146. changelist_filters = None
  147. if preserved_filters:
  148. changelist_filters = preserved_filters.get('_changelist_filters')
  149. if changelist_filters:
  150. changelist_url += '?' + changelist_filters
  151. if model_admin:
  152. queryset = model_admin.get_queryset(request)
  153. else:
  154. queryset = model.objects
  155. list_display = model_admin.get_list_display(request)
  156. list_display_links = model_admin.get_list_display_links(request, list_display)
  157. list_filter = model_admin.get_list_filter(request)
  158. search_fields = model_admin.get_search_fields(request) \
  159. if hasattr(model_admin, 'get_search_fields') else model_admin.search_fields
  160. list_select_related = model_admin.get_list_select_related(request) \
  161. if hasattr(model_admin, 'get_list_select_related') else model_admin.list_select_related
  162. actions = model_admin.get_actions(request)
  163. if actions:
  164. list_display = ['action_checkbox'] + list(list_display)
  165. ChangeList = model_admin.get_changelist(request)
  166. try:
  167. cl = ChangeList(
  168. request, model, list_display, list_display_links, list_filter, model_admin.date_hierarchy, search_fields,
  169. list_select_related, model_admin.list_per_page, model_admin.list_max_show_all, model_admin.list_editable,
  170. model_admin)
  171. queryset = cl.get_queryset(request)
  172. except IncorrectLookupParameters:
  173. pass
  174. return queryset
  175. def get_possible_language_codes():
  176. language_code = translation.get_language()
  177. language_code = language_code.replace('_', '-').lower()
  178. language_codes = []
  179. # making dialect part uppercase
  180. split = language_code.split('-', 2)
  181. if len(split) == 2:
  182. language_code = '%s-%s' % (split[0].lower(), split[1].upper()) if split[0] != split[1] else split[0]
  183. language_codes.append(language_code)
  184. # adding language code without dialect part
  185. if len(split) == 2:
  186. language_codes.append(split[0].lower())
  187. return language_codes