179 lines
5.3 KiB
Python
179 lines
5.3 KiB
Python
|
from __future__ import absolute_import
|
||
|
import copy
|
||
|
|
||
|
from django import forms
|
||
|
from django.contrib.contenttypes.models import ContentType
|
||
|
from django.core.exceptions import PermissionDenied
|
||
|
from django.db import models, transaction
|
||
|
from django.forms.models import modelform_factory
|
||
|
from django.http import Http404, HttpResponseRedirect
|
||
|
from django.template.response import TemplateResponse
|
||
|
from django.utils import six
|
||
|
from django.utils.encoding import force_text
|
||
|
from django.utils.html import escape
|
||
|
from django.template import loader
|
||
|
from django.utils.translation import ugettext as _
|
||
|
from xadmin import widgets
|
||
|
from xadmin.layout import FormHelper, Layout, Fieldset, TabHolder, Container, Column, Col, Field
|
||
|
from xadmin.util import unquote
|
||
|
from xadmin.views.detail import DetailAdminUtil
|
||
|
|
||
|
from .base import CommAdminView, filter_hook, csrf_protect_m
|
||
|
|
||
|
class FormAdminView(CommAdminView):
|
||
|
form = forms.ModelForm
|
||
|
title = None
|
||
|
readonly_fields = ()
|
||
|
|
||
|
form_template = 'xadmin/views/form.html'
|
||
|
|
||
|
form_layout = None
|
||
|
|
||
|
def init_request(self, *args, **kwargs):
|
||
|
# comm method for both get and post
|
||
|
self.prepare_form()
|
||
|
|
||
|
@filter_hook
|
||
|
def prepare_form(self):
|
||
|
self.view_form = self.form
|
||
|
|
||
|
@filter_hook
|
||
|
def instance_forms(self):
|
||
|
self.form_obj = self.view_form(**self.get_form_datas())
|
||
|
|
||
|
def setup_forms(self):
|
||
|
helper = self.get_form_helper()
|
||
|
if helper:
|
||
|
self.form_obj.helper = helper
|
||
|
|
||
|
@filter_hook
|
||
|
def valid_forms(self):
|
||
|
return self.form_obj.is_valid()
|
||
|
|
||
|
@filter_hook
|
||
|
def get_form_layout(self):
|
||
|
layout = copy.deepcopy(self.form_layout)
|
||
|
fields = self.form_obj.fields.keys()
|
||
|
|
||
|
if layout is None:
|
||
|
layout = Layout(Container(Col('full',
|
||
|
Fieldset("", *fields, css_class="unsort no_title"), horizontal=True, span=12)
|
||
|
))
|
||
|
elif type(layout) in (list, tuple) and len(layout) > 0:
|
||
|
if isinstance(layout[0], Column):
|
||
|
fs = layout
|
||
|
elif isinstance(layout[0], (Fieldset, TabHolder)):
|
||
|
fs = (Col('full', *layout, horizontal=True, span=12),)
|
||
|
else:
|
||
|
fs = (Col('full', Fieldset("", *layout, css_class="unsort no_title"), horizontal=True, span=12),)
|
||
|
|
||
|
layout = Layout(Container(*fs))
|
||
|
|
||
|
rendered_fields = [i[1] for i in layout.get_field_names()]
|
||
|
container = layout[0].fields
|
||
|
other_fieldset = Fieldset(_(u'Other Fields'), *[f for f in fields if f not in rendered_fields])
|
||
|
|
||
|
if len(other_fieldset.fields):
|
||
|
if len(container) and isinstance(container[0], Column):
|
||
|
container[0].fields.append(other_fieldset)
|
||
|
else:
|
||
|
container.append(other_fieldset)
|
||
|
|
||
|
return layout
|
||
|
|
||
|
@filter_hook
|
||
|
def get_form_helper(self):
|
||
|
helper = FormHelper()
|
||
|
helper.form_tag = False
|
||
|
helper.include_media = False
|
||
|
helper.add_layout(self.get_form_layout())
|
||
|
|
||
|
return helper
|
||
|
|
||
|
@filter_hook
|
||
|
def save_forms(self):
|
||
|
pass
|
||
|
|
||
|
@csrf_protect_m
|
||
|
@filter_hook
|
||
|
def get(self, request, *args, **kwargs):
|
||
|
self.instance_forms()
|
||
|
self.setup_forms()
|
||
|
|
||
|
return self.get_response()
|
||
|
|
||
|
@csrf_protect_m
|
||
|
@transaction.atomic
|
||
|
@filter_hook
|
||
|
def post(self, request, *args, **kwargs):
|
||
|
self.instance_forms()
|
||
|
self.setup_forms()
|
||
|
|
||
|
if self.valid_forms():
|
||
|
self.save_forms()
|
||
|
response = self.post_response()
|
||
|
cls_str = str if six.PY3 else basestring
|
||
|
if isinstance(response, cls_str):
|
||
|
return HttpResponseRedirect(response)
|
||
|
else:
|
||
|
return response
|
||
|
|
||
|
return self.get_response()
|
||
|
|
||
|
@filter_hook
|
||
|
def get_context(self):
|
||
|
context = super(FormAdminView, self).get_context()
|
||
|
context.update({
|
||
|
'form': self.form_obj,
|
||
|
'title': self.title,
|
||
|
})
|
||
|
return context
|
||
|
|
||
|
@filter_hook
|
||
|
def get_media(self):
|
||
|
return super(FormAdminView, self).get_media() + self.form_obj.media + \
|
||
|
self.vendor('xadmin.page.form.js', 'xadmin.form.css')
|
||
|
|
||
|
def get_initial_data(self):
|
||
|
return {}
|
||
|
|
||
|
@filter_hook
|
||
|
def get_form_datas(self):
|
||
|
data = {'initial': self.get_initial_data()}
|
||
|
if self.request_method == 'get':
|
||
|
data['initial'].update(self.request.GET)
|
||
|
else:
|
||
|
data.update({'data': self.request.POST, 'files': self.request.FILES})
|
||
|
return data
|
||
|
|
||
|
@filter_hook
|
||
|
def get_breadcrumb(self):
|
||
|
bcs = super(FormAdminView, self).get_breadcrumb()
|
||
|
bcs.append({'title': self.title})
|
||
|
return bcs
|
||
|
|
||
|
@filter_hook
|
||
|
def get_response(self):
|
||
|
context = self.get_context()
|
||
|
context.update(self.kwargs or {})
|
||
|
|
||
|
return TemplateResponse(
|
||
|
self.request, self.form_template,
|
||
|
context)
|
||
|
|
||
|
@filter_hook
|
||
|
def post_response(self):
|
||
|
request = self.request
|
||
|
|
||
|
msg = _('The %s was changed successfully.') % self.title
|
||
|
self.message_user(msg, 'success')
|
||
|
|
||
|
if "_redirect" in request.GET:
|
||
|
return request.GET["_redirect"]
|
||
|
else:
|
||
|
return self.get_redirect_url()
|
||
|
|
||
|
@filter_hook
|
||
|
def get_redirect_url(self):
|
||
|
return self.get_admin_url('index')
|