Repository: MongoEngine/mongoengine

Issue:
Allow to add custom metadata to fields
No we have only this tiny chunk of metadata which does not help a lot:

``` python
class BaseField(object):
    def __init__(self, ..., help_text=None):
        """
        ...
        :param help_text: (optional) The help text for this field and is often
        used when generating model forms from the document model.
        """
```

It would be great to have an option to attach custom name-value pairs (as generic dict) to the field class and have an access to them later. We need as much intention, incapsulated in fields, as possible to make generation easier (if possible, at all, cause corner cases are very hard now).



Discussion:
What kind of meta data do you need? What exactly is missing?


Resolving patch:
diff --git a/mongoengine/base/fields.py b/mongoengine/base/fields.py
--- a/mongoengine/base/fields.py
+++ b/mongoengine/base/fields.py
@@ -44,7 +44,7 @@ class BaseField(object):
     def __init__(self, db_field=None, name=None, required=False, default=None,
                  unique=False, unique_with=None, primary_key=False,
                  validation=None, choices=None, verbose_name=None,
-                 help_text=None, null=False, sparse=False):
+                 help_text=None, null=False, sparse=False, custom_data=None):
         """
         :param db_field: The database field to store this field in
             (defaults to the name of the field)
@@ -71,6 +71,7 @@ def __init__(self, db_field=None, name=None, required=False, default=None,
             then the default value is set
         :param sparse: (optional) `sparse=True` combined with `unique=True` and `required=False`
             means that uniqueness won't be enforced for `None` values
+        :param custom_data: (optional) Custom metadata for this field.
         """
         self.db_field = (db_field or name) if not primary_key else '_id'
 
@@ -89,6 +90,7 @@ def __init__(self, db_field=None, name=None, required=False, default=None,
         self.null = null
         self.sparse = sparse
         self._owner_document = None
+        self.custom_data = custom_data
 
         # Adjust the appropriate creation counter, and save our local copy.
         if self.db_field == '_id':


Test patch:
diff --git a/tests/fields/fields.py b/tests/fields/fields.py
--- a/tests/fields/fields.py
+++ b/tests/fields/fields.py
@@ -3818,5 +3818,22 @@ def test_filtered_delete(self):
         # deleted from the database
         self.assertEqual(number, 1)
 
+    def test_custom_data(self):
+        """
+        Tests that custom data is saved in the field object
+        and doesn't interfere with the rest of field functionalities.
+        """
+        custom_data = {'a': 'a_value', 'b': [1, 2]}
+        class CustomData(Document):
+            a_field = IntField()
+            c_field = IntField(custom_data=custom_data)
+
+        a1 = CustomData(a_field=1, c_field=2).save()
+        self.assertEqual(2, a1.c_field)
+        self.assertFalse(hasattr(a1.c_field, 'custom_data'))
+        self.assertTrue(hasattr(CustomData.c_field, 'custom_data'))
+        self.assertEqual(custom_data['a'], CustomData.c_field.custom_data['a'])
+
+
 if __name__ == '__main__':
     unittest.main()