Commit f6d0a10b authored by Serge S. Koval's avatar Serge S. Koval

MongoEngine inline forms now converted properly

parent ad5bc907
from wtforms.fields import FormField
class ModelFormField(FormField):
def __init__(self, model, *args, **kwargs):
super(ModelFormField, self).__init__(*args, **kwargs)
self.model = model
def populate_obj(self, obj, name):
candidate = getattr(obj, name, None)
if candidate is None:
candidate = self.model()
setattr(obj, name, candidate)
self.form.populate_obj(candidate)
...@@ -5,7 +5,10 @@ from wtforms import fields as f ...@@ -5,7 +5,10 @@ from wtforms import fields as f
from flask.ext.mongoengine.wtf import orm, fields from flask.ext.mongoengine.wtf import orm, fields
from flask.ext.admin import form from flask.ext.admin import form
from flask.ext.admin.model.fields import InlineFieldList, InlineModelFormField from flask.ext.admin.model.fields import InlineFieldList
from flask.ext.admin.model.widgets import InlineFormWidget
from .fields import ModelFormField
class CustomModelConverter(orm.ModelConverter): class CustomModelConverter(orm.ModelConverter):
...@@ -38,11 +41,11 @@ class CustomModelConverter(orm.ModelConverter): ...@@ -38,11 +41,11 @@ class CustomModelConverter(orm.ModelConverter):
kwargs = { kwargs = {
'validators': [], 'validators': [],
'filters': [], 'filters': [],
'widget': InlineModelFormField() 'widget': InlineFormWidget()
} }
form_class = model_form(field.document_type_obj, field_args={}) form_class = model_form(field.document_type_obj, field_args={})
return f.FormField(form_class, **kwargs) return ModelFormField(field.document_type_obj, form_class, **kwargs)
@orm.converts('ReferenceField') @orm.converts('ReferenceField')
def conv_Reference(self, model, field, kwargs): def conv_Reference(self, model, field, kwargs):
......
...@@ -220,7 +220,8 @@ class ModelView(BaseModelView): ...@@ -220,7 +220,8 @@ class ModelView(BaseModelView):
def create_model(self, form): def create_model(self, form):
try: try:
model = self.model(**form.data) model = self.model()
form.populate_obj(model)
self.on_model_change(form, model) self.on_model_change(form, model)
model.save() model.save()
return True return True
...@@ -232,12 +233,7 @@ class ModelView(BaseModelView): ...@@ -232,12 +233,7 @@ class ModelView(BaseModelView):
def update_model(self, form, model): def update_model(self, form, model):
try: try:
for f in form: form.populate_obj(model)
name, field = f.name, f
if hasattr(model, name) and getattr(model, name) != field.data:
setattr(model, name, field.data)
self.on_model_change(form, model) self.on_model_change(form, model)
model.save() model.save()
return True return True
......
...@@ -746,8 +746,6 @@ class BaseModelView(BaseView, ActionsMixin): ...@@ -746,8 +746,6 @@ class BaseModelView(BaseView, ActionsMixin):
value = rec_getattr(model, name) value = rec_getattr(model, name)
print name, type(value)
type_fmt = self.list_type_formatters.get(type(value)) type_fmt = self.list_type_formatters.get(type(value))
if type_fmt is not None: if type_fmt is not None:
value = type_fmt(value) value = type_fmt(value)
......
import itertools
from wtforms.fields import FieldList, FormField from wtforms.fields import FieldList, FormField
from .widgets import InlineFieldListWidget, InlineFormWidget from .widgets import InlineFieldListWidget, InlineFormWidget
...@@ -37,15 +39,24 @@ class InlineFieldList(FieldList): ...@@ -37,15 +39,24 @@ class InlineFieldList(FieldList):
return getattr(field, '_should_delete', False) return getattr(field, '_should_delete', False)
def populate_obj(self, obj, name): def populate_obj(self, obj, name):
result = [] values = getattr(obj, name, None)
try:
for f in self.entries: ivalues = iter(values)
if not self.should_delete(f): except TypeError:
field = self.field_type() ivalues = iter([])
f.populate_obj(field, None)
result.append(field) candidates = itertools.chain(ivalues, itertools.repeat(None))
_fake = type(str('_fake'), (object, ), {})
setattr(obj, self.prop, result)
output = []
for field, data in itertools.izip(self.entries, candidates):
if not self.should_delete(field):
fake_obj = _fake()
fake_obj.data = data
field.populate_obj(fake_obj, 'data')
output.append(fake_obj.data)
setattr(obj, name, output)
class InlineModelFormField(FormField): class InlineModelFormField(FormField):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment