Update forms app
Signed-off-by: Roberto Rosario <roberto.rosario.gonzalez@gmail.com>
This commit is contained in:
@@ -172,6 +172,22 @@ class DynamicFormMixin(object):
|
||||
kwargs.update(field_data.get('kwargs', {}))
|
||||
self.fields[field_name] = field_class(**kwargs)
|
||||
|
||||
def get_dynamic_values(self):
|
||||
# Consolidate the dynamic fields into a single dictionary.
|
||||
cleaned_data = super(DynamicFormMixin, self).clean()
|
||||
result = {}
|
||||
|
||||
for field_name, field_data in self.schema['fields'].items():
|
||||
result[field_name] = cleaned_data.pop(
|
||||
field_name, field_data.get('default', None)
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def set_dynamic_values(self, values):
|
||||
for key in self.schema['fields']:
|
||||
self.fields[key].initial = values.get(key, self.fields[key].initial)
|
||||
|
||||
|
||||
class DynamicForm(DynamicFormMixin, forms.Form):
|
||||
pass
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.contrib import admin
|
||||
|
||||
from .models import FieldChoice, FormTemplate, FormTemplateField
|
||||
from .models import FieldChoice, FormInstance, FormTemplate, FormTemplateField
|
||||
|
||||
|
||||
@admin.register(FieldChoice)
|
||||
@@ -10,6 +10,11 @@ class FieldChoiceAdmin(admin.ModelAdmin):
|
||||
list_display = ('label', 'dotted_path')
|
||||
|
||||
|
||||
@admin.register(FormInstance)
|
||||
class FormInstanceAdmin(admin.ModelAdmin):
|
||||
list_display = ('form_template', 'data')
|
||||
|
||||
|
||||
class FormTemplateFieldInline(admin.StackedInline):
|
||||
model = FormTemplateField
|
||||
extra = 1
|
||||
|
||||
@@ -18,6 +18,8 @@ from mayan.apps.events.links import (
|
||||
)
|
||||
from mayan.apps.navigation.classes import SourceColumn
|
||||
|
||||
from .classes import FieldClass
|
||||
|
||||
|
||||
class FormsApp(MayanAppConfig):
|
||||
app_namespace = 'forms'
|
||||
@@ -28,3 +30,4 @@ class FormsApp(MayanAppConfig):
|
||||
|
||||
def ready(self):
|
||||
super(FormsApp, self).ready()
|
||||
FieldClass.initialize()
|
||||
|
||||
@@ -1,28 +1,64 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from importlib import import_module
|
||||
import logging
|
||||
|
||||
from django.apps import apps
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FieldEntry(object):
|
||||
class FieldClass(object):
|
||||
_registry = {}
|
||||
|
||||
@staticmethod
|
||||
def initialize():
|
||||
for app in apps.get_app_configs():
|
||||
try:
|
||||
import_module('{}.form_fields'.format(app.name))
|
||||
except ImportError as exception:
|
||||
if force_text(exception) not in ('No module named form_fields', 'No module named \'{}.form_fields\''.format(app.name)):
|
||||
logger.error(
|
||||
'Error importing %s queues.py file; %s', app.name,
|
||||
exception
|
||||
)
|
||||
raise
|
||||
|
||||
FieldClass.update()
|
||||
|
||||
@classmethod
|
||||
def all(cls):
|
||||
return cls._registry.values()
|
||||
|
||||
@classmethod
|
||||
def update(cls):
|
||||
FieldChoice = apps.get_model(
|
||||
app_label='forms', model_name='FieldChoice'
|
||||
)
|
||||
|
||||
for field in cls.all():
|
||||
FieldChoice.objects.update_or_create(
|
||||
dotted_path=field.dotted_path, defaults={
|
||||
'label': field.label
|
||||
}
|
||||
)
|
||||
|
||||
def __init__(self, dotted_path, label):
|
||||
self.dotted_path = dotted_path
|
||||
self.label = label
|
||||
|
||||
self.__class__._registry[self.dotted_path] = self
|
||||
|
||||
|
||||
|
||||
FieldEntry(dotted_path='django.forms.CharField', label='Character field')
|
||||
def validate(self):
|
||||
try:
|
||||
import_string(dotted_path=self.dotted_path)
|
||||
except Exception as exception:
|
||||
logger.critical(
|
||||
'Exception validating field entry %s; %s', self.label, exception,
|
||||
exc_info=True
|
||||
)
|
||||
raise
|
||||
|
||||
8
mayan/apps/forms/form_fields.py
Normal file
8
mayan/apps/forms/form_fields.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .classes import FieldClass
|
||||
|
||||
|
||||
FieldClass(dotted_path='django.forms.CharField', label=_('Character field'))
|
||||
82
mayan/apps/forms/forms.py
Normal file
82
mayan/apps/forms/forms.py
Normal file
@@ -0,0 +1,82 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import json
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from mayan.apps.acls.models import AccessControlList
|
||||
from mayan.apps.common.forms import DynamicModelForm
|
||||
#from mayan.apps.common.settings import setting_project_title, setting_project_url
|
||||
|
||||
#from .classes import MailerBackend
|
||||
#from .models import UserMailer
|
||||
#from .permissions import permission_user_mailer_use
|
||||
#from .settings import (
|
||||
# setting_document_body_template, setting_document_subject_template,
|
||||
# setting_link_body_template, setting_link_subject_template
|
||||
#)
|
||||
#from .validators import validate_email_multiple
|
||||
|
||||
from .models import FormInstance
|
||||
|
||||
|
||||
class FormInstanceDynamicForm(DynamicModelForm):
|
||||
class Meta:
|
||||
#fields = ('label', 'default', 'enabled', 'backend_data')
|
||||
fields = ('data',)
|
||||
model = FormInstance
|
||||
widgets = {'data': forms.widgets.HiddenInput}
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
result = super(FormInstanceDynamicForm, self).__init__(*args, **kwargs)
|
||||
|
||||
if self.instance:
|
||||
#print("!!!!!!!!!!! instace data", self.instance.get_data())
|
||||
##print("!!!!!!!!!!! instace data", type(self.instance.get_data()))
|
||||
print("!!!!!!!!!!! instace data", self.instance.data)
|
||||
print("!!!!!!!!!!! instace data", type(self.instance.data))
|
||||
self.set_dynamic_values(values=self.instance.data)
|
||||
|
||||
"""
|
||||
|
||||
instance_data = self.instance.get_data()
|
||||
|
||||
if instance_data:
|
||||
#print("@@@@@@@@@!!!!!!!!!!!! self.instance.data", self.instance.data)
|
||||
#print("@@@@@@@@@!!!!!!!!!!!! data", data)
|
||||
#print("@@@@@@@@@!!!!!!!!!!!! type: data", type(data))
|
||||
#print("@@@@@@@@@!!!!!!!!!!!! self.fields", self.fields)
|
||||
#print("@@@@@@@@@!!!!!!!!!!!! self.fields", self.fields.keys())
|
||||
for key in self.instance.form_template.get_fields_dictionary():
|
||||
#print("@@@@@@@@@@@key", key)
|
||||
#print("@@@@@@@@@@@key", type(data))
|
||||
#print("@@@@@@@@@@@key", data[key])
|
||||
self.fields[key].initial = instance_data[key]
|
||||
|
||||
return result
|
||||
"""
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(FormInstanceDynamicForm, self).clean()
|
||||
cleaned_data['data'] = json.dumps(self.get_dynamic_values())
|
||||
return cleaned_data
|
||||
|
||||
"""
|
||||
|
||||
cleaned_data = super(FormInstanceDynamicForm, self).clean()
|
||||
|
||||
# Consolidate the dynamic fields into a single JSON field called
|
||||
# 'backend_data'.
|
||||
form_instance_data = {}
|
||||
|
||||
for field_name, field_data in self.schema['fields'].items():
|
||||
form_instance_data[field_name] = cleaned_data.pop(
|
||||
field_name, field_data.get('default', None)
|
||||
)
|
||||
|
||||
print("!!!!!!!!!!!!!!!!!! form_instance_data", form_instance_data)
|
||||
#cleaned_data['data'] = json.dumps(form_instance_data)
|
||||
cleaned_data['data'] = form_instance_data
|
||||
return cleaned_data
|
||||
"""
|
||||
@@ -30,6 +30,7 @@ class FieldChoice(models.Model):
|
||||
return self.label
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class FormTemplate(models.Model):
|
||||
name = models.CharField(max_length=32, verbose_name=_('Name'))
|
||||
label = models.CharField(max_length=128, verbose_name=_('Label'))
|
||||
@@ -40,6 +41,9 @@ class FormTemplate(models.Model):
|
||||
verbose_name = _('Form template')
|
||||
verbose_name_plural = _('Form templates')
|
||||
|
||||
def __str__(self):
|
||||
return self.label
|
||||
|
||||
def get_fields_dictionary(self):
|
||||
result = {}
|
||||
|
||||
@@ -84,8 +88,34 @@ class FormTemplateField(models.Model):
|
||||
return json.loads(self.arguments or '{}')
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class FormInstance(models.Model):
|
||||
form_template = models.ForeignKey(
|
||||
on_delete=models.CASCADE, related_name='instances', to=FormTemplate,
|
||||
verbose_name=_('Form template field')
|
||||
)
|
||||
data = models.TextField(
|
||||
blank=True, verbose_name=_('Data')
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FormInstance, self).__init__(*args, **kwargs)
|
||||
self.deserialize_data()
|
||||
|
||||
def __str__(self):
|
||||
return force_text(self.form_template)
|
||||
|
||||
class Meta:
|
||||
verbose_name = _('Form instance')
|
||||
verbose_name_plural = _('Form instances')
|
||||
|
||||
def deserialize_data(self):
|
||||
self.data = json.loads(self.data or '{}')
|
||||
|
||||
def serialize_data(self):
|
||||
self.data = json.dumps(self.data or {})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
#if not self.pk:
|
||||
self.serialize_data()
|
||||
return super(FormInstance, self).save(*args, **kwargs)
|
||||
|
||||
@@ -2,11 +2,15 @@ from __future__ import unicode_literals
|
||||
|
||||
from django.conf.urls import url
|
||||
|
||||
from .views import FormInstanceCreateView
|
||||
from .views import FormInstanceCreateView, FormInstanceEditView
|
||||
|
||||
urlpatterns = [
|
||||
url(
|
||||
regex=r'^templates/(?P<pk>\d+)/instances/create/$',
|
||||
view=FormInstanceCreateView.as_view(), name='form_instance_create'
|
||||
),
|
||||
url(
|
||||
regex=r'^instances/(?P<pk>\d+)/edit/$',
|
||||
view=FormInstanceEditView.as_view(), name='form_instance_edit'
|
||||
),
|
||||
]
|
||||
|
||||
@@ -17,7 +17,7 @@ from mayan.apps.common.mixins import ExternalObjectMixin
|
||||
|
||||
from .models import FormTemplate, FormInstance
|
||||
|
||||
|
||||
"""
|
||||
class FormInstanceCreateView(ExternalObjectMixin, DynamicFormView):
|
||||
external_object_class = FormTemplate
|
||||
external_object_pk_url_kwarg = 'pk'
|
||||
@@ -29,4 +29,66 @@ class FormInstanceCreateView(ExternalObjectMixin, DynamicFormView):
|
||||
'widgets': {}
|
||||
}
|
||||
|
||||
return result
|
||||
"""
|
||||
|
||||
|
||||
from .forms import FormInstanceDynamicForm
|
||||
|
||||
class FormInstanceCreateView(ExternalObjectMixin, SingleObjectDynamicFormCreateView):
|
||||
external_object_class = FormTemplate
|
||||
external_object_pk_url_kwarg = 'pk'
|
||||
form_class = FormInstanceDynamicForm
|
||||
#post_action_redirect = reverse_lazy(viewname='mailer:user_mailer_list')
|
||||
#view_permission = permission_user_mailer_create
|
||||
|
||||
#def get_backend(self):
|
||||
# try:
|
||||
# return MailerBackend.get(name=self.kwargs['class_path'])
|
||||
# except KeyError:
|
||||
# raise Http404(
|
||||
# '{} class not found'.format(self.kwargs['class_path'])
|
||||
# )
|
||||
|
||||
#def get_extra_context(self):
|
||||
# return {
|
||||
# 'title': _(
|
||||
# 'Create a "%s" mailing profile'
|
||||
# ) % self.get_backend().label,
|
||||
# }
|
||||
|
||||
def get_form_schema(self):
|
||||
result = {
|
||||
'fields': self.external_object.get_fields_dictionary(),
|
||||
'widgets': {}
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
|
||||
#def get_form_schema(self):
|
||||
# backend = self.get_backend()
|
||||
# result = {
|
||||
# 'fields': backend.fields,
|
||||
# 'widgets': getattr(backend, 'widgets', {})
|
||||
# }
|
||||
# if hasattr(backend, 'field_order'):
|
||||
# result['field_order'] = backend.field_order
|
||||
|
||||
# return result
|
||||
|
||||
def get_instance_extra_data(self):
|
||||
return {'form_template': self.external_object}
|
||||
|
||||
|
||||
class FormInstanceEditView(SingleObjectDynamicFormEditView):
|
||||
model = FormInstance
|
||||
form_class = FormInstanceDynamicForm
|
||||
|
||||
def get_form_schema(self):
|
||||
result = {
|
||||
'fields': self.object.form_template.get_fields_dictionary(),
|
||||
'widgets': {}
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
Reference in New Issue
Block a user