form.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. from __future__ import absolute_import
  2. import copy
  3. from django import forms
  4. from django.contrib.contenttypes.models import ContentType
  5. from django.core.exceptions import PermissionDenied
  6. from django.db import models, transaction
  7. from django.forms.models import modelform_factory
  8. from django.http import Http404, HttpResponseRedirect
  9. from django.template.response import TemplateResponse
  10. from django.utils import six
  11. from django.utils.encoding import force_text
  12. from django.utils.html import escape
  13. from django.template import loader
  14. from django.utils.translation import ugettext as _
  15. from xadmin import widgets
  16. from xadmin.layout import FormHelper, Layout, Fieldset, TabHolder, Container, Column, Col, Field
  17. from xadmin.util import unquote
  18. from xadmin.views.detail import DetailAdminUtil
  19. from .base import CommAdminView, filter_hook, csrf_protect_m
  20. class FormAdminView(CommAdminView):
  21. form = forms.ModelForm
  22. title = None
  23. readonly_fields = ()
  24. form_template = 'xadmin/views/form.html'
  25. form_layout = None
  26. def init_request(self, *args, **kwargs):
  27. # comm method for both get and post
  28. self.prepare_form()
  29. @filter_hook
  30. def prepare_form(self):
  31. self.view_form = self.form
  32. @filter_hook
  33. def instance_forms(self):
  34. self.form_obj = self.view_form(**self.get_form_datas())
  35. def setup_forms(self):
  36. helper = self.get_form_helper()
  37. if helper:
  38. self.form_obj.helper = helper
  39. @filter_hook
  40. def valid_forms(self):
  41. return self.form_obj.is_valid()
  42. @filter_hook
  43. def get_form_layout(self):
  44. layout = copy.deepcopy(self.form_layout)
  45. fields = self.form_obj.fields.keys()
  46. if layout is None:
  47. layout = Layout(Container(Col('full',
  48. Fieldset("", *fields, css_class="unsort no_title"), horizontal=True, span=12)
  49. ))
  50. elif type(layout) in (list, tuple) and len(layout) > 0:
  51. if isinstance(layout[0], Column):
  52. fs = layout
  53. elif isinstance(layout[0], (Fieldset, TabHolder)):
  54. fs = (Col('full', *layout, horizontal=True, span=12),)
  55. else:
  56. fs = (Col('full', Fieldset("", *layout, css_class="unsort no_title"), horizontal=True, span=12),)
  57. layout = Layout(Container(*fs))
  58. rendered_fields = [i[1] for i in layout.get_field_names()]
  59. container = layout[0].fields
  60. other_fieldset = Fieldset(_(u'Other Fields'), *[f for f in fields if f not in rendered_fields])
  61. if len(other_fieldset.fields):
  62. if len(container) and isinstance(container[0], Column):
  63. container[0].fields.append(other_fieldset)
  64. else:
  65. container.append(other_fieldset)
  66. return layout
  67. @filter_hook
  68. def get_form_helper(self):
  69. helper = FormHelper()
  70. helper.form_tag = False
  71. helper.include_media = False
  72. helper.add_layout(self.get_form_layout())
  73. return helper
  74. @filter_hook
  75. def save_forms(self):
  76. pass
  77. @csrf_protect_m
  78. @filter_hook
  79. def get(self, request, *args, **kwargs):
  80. self.instance_forms()
  81. self.setup_forms()
  82. return self.get_response()
  83. @csrf_protect_m
  84. @transaction.atomic
  85. @filter_hook
  86. def post(self, request, *args, **kwargs):
  87. self.instance_forms()
  88. self.setup_forms()
  89. if self.valid_forms():
  90. self.save_forms()
  91. response = self.post_response()
  92. cls_str = str if six.PY3 else basestring
  93. if isinstance(response, cls_str):
  94. return HttpResponseRedirect(response)
  95. else:
  96. return response
  97. return self.get_response()
  98. @filter_hook
  99. def get_context(self):
  100. context = super(FormAdminView, self).get_context()
  101. context.update({
  102. 'form': self.form_obj,
  103. 'title': self.title,
  104. })
  105. return context
  106. @filter_hook
  107. def get_media(self):
  108. return super(FormAdminView, self).get_media() + self.form_obj.media + \
  109. self.vendor('xadmin.page.form.js', 'xadmin.form.css')
  110. def get_initial_data(self):
  111. return {}
  112. @filter_hook
  113. def get_form_datas(self):
  114. data = {'initial': self.get_initial_data()}
  115. if self.request_method == 'get':
  116. data['initial'].update(self.request.GET)
  117. else:
  118. data.update({'data': self.request.POST, 'files': self.request.FILES})
  119. return data
  120. @filter_hook
  121. def get_breadcrumb(self):
  122. bcs = super(FormAdminView, self).get_breadcrumb()
  123. bcs.append({'title': self.title})
  124. return bcs
  125. @filter_hook
  126. def get_response(self):
  127. context = self.get_context()
  128. context.update(self.kwargs or {})
  129. return TemplateResponse(
  130. self.request, self.form_template,
  131. context)
  132. @filter_hook
  133. def post_response(self):
  134. request = self.request
  135. msg = _('The %s was changed successfully.') % self.title
  136. self.message_user(msg, 'success')
  137. if "_redirect" in request.GET:
  138. return request.GET["_redirect"]
  139. else:
  140. return self.get_redirect_url()
  141. @filter_hook
  142. def get_redirect_url(self):
  143. return self.get_admin_url('index')