Skip to content

Commit dfac8cc

Browse files
committed
Merge pull request #147 from losintikfos/master
Model form generator now accepts wtf custom 'validators' and 'filters' on model field definition.
2 parents e0117fa + 2331023 commit dfac8cc

File tree

4 files changed

+88
-3
lines changed

4 files changed

+88
-3
lines changed

flask_mongoengine/__init__.py

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import
3+
import inspect
34

45
from flask import abort, current_app
56

@@ -13,6 +14,45 @@
1314
from .sessions import *
1415
from .pagination import *
1516
from .json import overide_json_encoder
17+
from .wtf import WtfBaseField
18+
19+
20+
def _patch_base_field(object, name):
21+
"""
22+
If the object submitted has a class whose base class is
23+
mongoengine.base.fields.BaseField, then monkey patch to
24+
replace it with flask_mongoengine.wtf.WtfBaseField.
25+
26+
@note: WtfBaseField is an instance of BaseField - but
27+
gives us the flexibility to extend field parameters
28+
and settings required of WTForm via model form generator.
29+
30+
@see: flask_mongoengine.wtf.base.WtfBaseField.
31+
@see: model_form in flask_mongoengine.wtf.orm
32+
33+
@param object: The object whose footprint to locate the class.
34+
@param name: Name of the class to locate.
35+
36+
"""
37+
# locate class
38+
cls = getattr(object, name)
39+
if not inspect.isclass(cls):
40+
return
41+
42+
# fetch class base classes
43+
cls_bases = list(cls.__bases__)
44+
45+
# replace BaseField with WtfBaseField
46+
for index, base in enumerate(cls_bases):
47+
if base == mongoengine.base.fields.BaseField:
48+
cls_bases[index] = WtfBaseField
49+
cls.__bases__ = tuple(cls_bases)
50+
break
51+
52+
# re-assign class back to
53+
# object footprint
54+
delattr(object, name)
55+
setattr(object, name, cls)
1656

1757

1858
def _include_mongoengine(obj):
@@ -21,6 +61,9 @@ def _include_mongoengine(obj):
2161
if not hasattr(obj, key):
2262
setattr(obj, key, getattr(module, key))
2363

64+
# patch BaseField if available
65+
_patch_base_field(obj, key)
66+
2467

2568
def _create_connection(conn_settings):
2669

@@ -44,10 +87,10 @@ def _create_connection(conn_settings):
4487
return mongoengine.connect(conn.pop('db', 'test'), **conn)
4588

4689

90+
4791
class MongoEngine(object):
4892

4993
def __init__(self, app=None, config=None):
50-
5194
_include_mongoengine(self)
5295

5396
self.Document = Document

flask_mongoengine/wtf/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
from flask.ext.mongoengine.wtf.orm import model_fields, model_form
2+
from flask.ext.mongoengine.wtf.base import WtfBaseField

flask_mongoengine/wtf/base.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from mongoengine.base import BaseField
2+
3+
__all__ = ('WtfBaseField')
4+
5+
class WtfBaseField(BaseField):
6+
"""
7+
Extension wrapper class for mongoengine BaseField.
8+
9+
This enables flask-mongoengine wtf to extend the
10+
number of field parameters, and settings on behalf
11+
of document model form generator for WTForm.
12+
13+
@param validators: wtf model form field validators.
14+
@param filters: wtf model form field filters.
15+
"""
16+
17+
def __init__(self, validators=None, filters=None, **kwargs):
18+
19+
self.validators =\
20+
self._ensure_callable_or_list(validators, 'validators')
21+
self.filters = self._ensure_callable_or_list(filters, 'filters')
22+
23+
BaseField.__init__(self, **kwargs)
24+
25+
26+
def _ensure_callable_or_list(self, field, msg_flag):
27+
"""
28+
Ensure the value submitted via field is either
29+
a callable object to convert to list or it is
30+
in fact a valid list value.
31+
32+
"""
33+
if field is not None:
34+
if callable(field):
35+
field = [field]
36+
else:
37+
msg = "Argument '%s' must be a list value" % msg_flag
38+
if not isinstance(field, list):
39+
raise TypeError(msg)
40+
41+
return field

flask_mongoengine/wtf/orm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def convert(self, model, field, field_args):
4747
kwargs = {
4848
'label': getattr(field, 'verbose_name', field.name),
4949
'description': field.help_text or '',
50-
'validators': [],
51-
'filters': [],
50+
'validators': [] if not field.validators else field.validators,
51+
'filters': [] if not field.filters else field.filters,
5252
'default': field.default,
5353
}
5454
if field_args:

0 commit comments

Comments
 (0)