ajax.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from collections import OrderedDict
  2. from django.forms.utils import ErrorDict
  3. from django.utils.html import escape
  4. from django.utils.encoding import force_text
  5. from xadmin.sites import site
  6. from xadmin.views import BaseAdminPlugin, ListAdminView, ModelFormAdminView, DetailAdminView
  7. NON_FIELD_ERRORS = '__all__'
  8. class BaseAjaxPlugin(BaseAdminPlugin):
  9. def init_request(self, *args, **kwargs):
  10. return bool(self.request.is_ajax() or self.request.GET.get('_ajax'))
  11. class AjaxListPlugin(BaseAjaxPlugin):
  12. def get_list_display(self,list_display):
  13. list_fields = [field for field in self.request.GET.get('_fields',"").split(",")
  14. if field.strip() != ""]
  15. if list_fields:
  16. return list_fields
  17. return list_display
  18. def get_result_list(self, response):
  19. av = self.admin_view
  20. base_fields = self.get_list_display(av.base_list_display)
  21. headers = dict([(c.field_name, force_text(c.text)) for c in av.result_headers(
  22. ).cells if c.field_name in base_fields])
  23. objects = [dict([(o.field_name, escape(str(o.value))) for i, o in
  24. enumerate(filter(lambda c:c.field_name in base_fields, r.cells))])
  25. for r in av.results()]
  26. return self.render_response({'headers': headers, 'objects': objects, 'total_count': av.result_count, 'has_more': av.has_more})
  27. class JsonErrorDict(ErrorDict):
  28. def __init__(self, errors, form):
  29. super(JsonErrorDict, self).__init__(errors)
  30. self.form = form
  31. def as_json(self):
  32. if not self:
  33. return u''
  34. return [{'id': self.form[k].auto_id if k != NON_FIELD_ERRORS else NON_FIELD_ERRORS, 'name': k, 'errors': v} for k, v in self.items()]
  35. class AjaxFormPlugin(BaseAjaxPlugin):
  36. def post_response(self, __):
  37. new_obj = self.admin_view.new_obj
  38. return self.render_response({
  39. 'result': 'success',
  40. 'obj_id': new_obj.pk,
  41. 'obj_repr': str(new_obj),
  42. 'change_url': self.admin_view.model_admin_url('change', new_obj.pk),
  43. 'detail_url': self.admin_view.model_admin_url('detail', new_obj.pk)
  44. })
  45. def get_response(self, __):
  46. if self.request.method.lower() != 'post':
  47. return __()
  48. result = {}
  49. form = self.admin_view.form_obj
  50. if form.is_valid():
  51. result['result'] = 'success'
  52. else:
  53. result['result'] = 'error'
  54. result['errors'] = JsonErrorDict(form.errors, form).as_json()
  55. return self.render_response(result)
  56. class AjaxDetailPlugin(BaseAjaxPlugin):
  57. def get_response(self, __):
  58. if self.request.GET.get('_format') == 'html':
  59. self.admin_view.detail_template = 'xadmin/views/quick_detail.html'
  60. return __()
  61. form = self.admin_view.form_obj
  62. layout = form.helper.layout
  63. results = []
  64. for p, f in layout.get_field_names():
  65. result = self.admin_view.get_field_result(f)
  66. results.append((result.label, result.val))
  67. return self.render_response(OrderedDict(results))
  68. site.register_plugin(AjaxListPlugin, ListAdminView)
  69. site.register_plugin(AjaxFormPlugin, ModelFormAdminView)
  70. site.register_plugin(AjaxDetailPlugin, DetailAdminView)