diff --git a/mongoforms/fields.py b/mongoforms/fields.py index 5079591..5f1366c 100644 --- a/mongoforms/fields.py +++ b/mongoforms/fields.py @@ -2,8 +2,29 @@ from django.utils.encoding import smart_unicode from bson.errors import InvalidId from bson.objectid import ObjectId +from mongoengine import StringField + + +class ListField(forms.Field): + """ + List field for mongo forms. + Uses MultiValueField from django.forms module. + """ + field_name_separator = '__' + + def __init__(self, field, field_name_base, list_size=2, *args, **kwargs): + forms.Field.__init__(self, *args, **kwargs) + self.fields = [] + + field_generator = MongoFormFieldGenerator() + + for field_num in range(list_size): + field_name = '%s%s%s' % (field_name_base, + self.field_name_separator, field_num) + self.fields.append(field_generator.generate(field_name, field)) + class ReferenceField(forms.ChoiceField): """ Reference field for mongo forms. Inspired by `django.forms.models.ModelChoiceField`. @@ -154,3 +175,13 @@ def generate_referencefield(self, field_name, field, label): return ReferenceField( field.document_type.objects, label=label) + + # Custom + def generate_listfield(self, field_name, field, label): + return ListField( + label=label, + field=field.field, + field_name_base=field_name, + required=field.required, + initial=field.default) + \ No newline at end of file diff --git a/mongoforms/forms.py b/mongoforms/forms.py index 6302a55..efd2466 100644 --- a/mongoforms/forms.py +++ b/mongoforms/forms.py @@ -78,12 +78,21 @@ def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, # walk through the document fields for field_name, field in iter_valid_fields(self._meta): # add field data if needed + if not hasattr(instance, field_name): + continue field_data = getattr(instance, field_name) - if isinstance(self._meta.document._fields[field_name], ReferenceField): - # field data could be None for not populated refs - field_data = field_data and str(field_data.id) + if not self._meta.document._dynamic: + fields = self._meta.document._fields + # add dfields if document is dynamic + elif hasattr(self._meta.document, '_dfields'): + fields = self._meta.document._dfields + else: + continue + if field_name in fields: + _field = fields[field_name] + if isinstance(_field, ReferenceField): + field_data = field_data and str(field_data.id) object_data[field_name] = field_data - # additional initial data available? if initial is not None: object_data.update(initial) diff --git a/mongoforms/utils.py b/mongoforms/utils.py index 533f1d0..8c8f58b 100644 --- a/mongoforms/utils.py +++ b/mongoforms/utils.py @@ -39,3 +39,8 @@ def iter_valid_fields(meta): # skip excluded fields if field_name not in meta_exclude: yield (field_name, field) + + # walk through meta dfields + if meta.document._dynamic and hasattr(meta.document, '_dfields'): + for field_name, field in meta.document._dfields.iteritems(): + yield (field_name, field) \ No newline at end of file