-
Notifications
You must be signed in to change notification settings - Fork 16
/
base.py
65 lines (54 loc) · 2.18 KB
/
base.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import copy
import jinja2
import wtforms
from wtforms.fields.core import UnboundField
from wtforms.validators import Optional, InputRequired
from flask import render_template
from sqlalchemy.sql.elements import TextClause
class BaseWidget:
filterable = True
field = wtforms.StringField()
field_kwargs = {}
def __init__(self, name, meta, model):
self.name = name
self.meta = meta
self.model = model
self.field = copy.deepcopy(self.field)
if self.field is not None:
self.field.label = self.pretty_name
self.field.default = self.default
if isinstance(self.field, wtforms.BooleanField) \
or (isinstance(self.field, UnboundField) and self.field.field_class == wtforms.BooleanField):
# because I didn't find how to handle InputRequired for BooleanField :(
extra_validators = [Optional()]
else:
extra_validators = [Optional() if self.nullable or self.default is not None else InputRequired()]
self.field.kwargs["validators"] = list(
set(self.field.kwargs.get("validators") or []) | set(extra_validators)
)
@property
def pretty_name(self):
return self.name.replace("_", " ")
@property
def default(self):
if self.meta.default or self.meta.server_default:
default = (self.meta.default or self.meta.server_default).arg
if isinstance(default, TextClause):
default = ""
else:
default = None
return default
@property
def nullable(self):
return self.meta.nullable
def render_edit(self, form=None, item=None):
if form:
return form[self.name](**self.field_kwargs)
value = str(getattr(item, self.name, None) or "")
value = jinja2.escape(value)
return render_template("widgets/text.html", name=self.name, value=value, default=self.default)
def render_list(self, item):
value = getattr(item, self.name, None)
return jinja2.escape(str(value)) if value is not None else "null"
def render_details(self, item):
return self.render_list(item)