123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- from __future__ import unicode_literals
- import decimal
- import operator
- from wtforms import fields, widgets
- from wtforms.compat import text_type, string_types
- class ReferencePropertyField(fields.SelectFieldBase):
- """
- A field for ``db.ReferenceProperty``. The list items are rendered in a
- select.
- :param reference_class:
- A db.Model class which will be used to generate the default query
- to make the list of items. If this is not specified, The `query`
- property must be overridden before validation.
- :param get_label:
- If a string, use this attribute on the model class as the label
- associated with each option. If a one-argument callable, this callable
- will be passed model instance and expected to return the label text.
- Otherwise, the model object's `__str__` or `__unicode__` will be used.
- :param allow_blank:
- If set to true, a blank choice will be added to the top of the list
- to allow `None` to be chosen.
- :param blank_text:
- Use this to override the default blank option's label.
- """
- widget = widgets.Select()
- def __init__(self, label=None, validators=None, reference_class=None,
- get_label=None, allow_blank=False,
- blank_text='', **kwargs):
- super(ReferencePropertyField, self).__init__(label, validators,
- **kwargs)
- if get_label is None:
- self.get_label = lambda x: x
- elif isinstance(get_label, string_types):
- self.get_label = operator.attrgetter(get_label)
- else:
- self.get_label = get_label
- self.allow_blank = allow_blank
- self.blank_text = blank_text
- self._set_data(None)
- if reference_class is not None:
- self.query = reference_class.all()
- def _get_data(self):
- if self._formdata is not None:
- for obj in self.query:
- if str(obj.key()) == self._formdata:
- self._set_data(obj)
- break
- return self._data
- def _set_data(self, data):
- self._data = data
- self._formdata = None
- data = property(_get_data, _set_data)
- def iter_choices(self):
- if self.allow_blank:
- yield ('__None', self.blank_text, self.data is None)
- for obj in self.query:
- key = str(obj.key())
- label = self.get_label(obj)
- yield (key, label, (self.data.key() == obj.key()) if self.data else False)
- def process_formdata(self, valuelist):
- if valuelist:
- if valuelist[0] == '__None':
- self.data = None
- else:
- self._data = None
- self._formdata = valuelist[0]
- def pre_validate(self, form):
- if not self.allow_blank or self.data is not None:
- for obj in self.query:
- if str(self.data.key()) == str(obj.key()):
- break
- else:
- raise ValueError(self.gettext('Not a valid choice'))
- class KeyPropertyField(fields.SelectFieldBase):
- """
- A field for ``ndb.KeyProperty``. The list items are rendered in a select.
- :param reference_class:
- A db.Model class which will be used to generate the default query
- to make the list of items. If this is not specified, The `query`
- property must be overridden before validation.
- :param get_label:
- If a string, use this attribute on the model class as the label
- associated with each option. If a one-argument callable, this callable
- will be passed model instance and expected to return the label text.
- Otherwise, the model object's `__str__` or `__unicode__` will be used.
- :param allow_blank:
- If set to true, a blank choice will be added to the top of the list
- to allow `None` to be chosen.
- :param blank_text:
- Use this to override the default blank option's label.
- """
- widget = widgets.Select()
- def __init__(self, label=None, validators=None, reference_class=None,
- get_label=None, allow_blank=False, blank_text='', **kwargs):
- super(KeyPropertyField, self).__init__(label, validators, **kwargs)
- if get_label is None:
- self.get_label = lambda x: x
- elif isinstance(get_label, basestring):
- self.get_label = operator.attrgetter(get_label)
- else:
- self.get_label = get_label
- self.allow_blank = allow_blank
- self.blank_text = blank_text
- self._set_data(None)
- if reference_class is not None:
- self.query = reference_class.query()
- def _get_data(self):
- if self._formdata is not None:
- for obj in self.query:
- if str(obj.key.id()) == self._formdata:
- self._set_data(obj)
- break
- return self._data
- def _set_data(self, data):
- self._data = data
- self._formdata = None
- data = property(_get_data, _set_data)
- def iter_choices(self):
- if self.allow_blank:
- yield ('__None', self.blank_text, self.data is None)
- for obj in self.query:
- key = str(obj.key.id())
- label = self.get_label(obj)
- yield (key, label, (self.data.key == obj.key) if self.data else False)
- def process_formdata(self, valuelist):
- if valuelist:
- if valuelist[0] == '__None':
- self.data = None
- else:
- self._data = None
- self._formdata = valuelist[0]
- def pre_validate(self, form):
- if self.data is not None:
- for obj in self.query:
- if self.data.key == obj.key:
- break
- else:
- raise ValueError(self.gettext('Not a valid choice'))
- elif not self.allow_blank:
- raise ValueError(self.gettext('Not a valid choice'))
- class StringListPropertyField(fields.TextAreaField):
- """
- A field for ``db.StringListProperty``. The list items are rendered in a
- textarea.
- """
- def _value(self):
- if self.raw_data:
- return self.raw_data[0]
- else:
- return self.data and text_type("\n".join(self.data)) or ''
- def process_formdata(self, valuelist):
- if valuelist:
- try:
- self.data = valuelist[0].splitlines()
- except ValueError:
- raise ValueError(self.gettext('Not a valid list'))
- class IntegerListPropertyField(fields.TextAreaField):
- """
- A field for ``db.StringListProperty``. The list items are rendered in a
- textarea.
- """
- def _value(self):
- if self.raw_data:
- return self.raw_data[0]
- else:
- return text_type('\n'.join(self.data)) if self.data else ''
- def process_formdata(self, valuelist):
- if valuelist:
- try:
- self.data = [int(value) for value in valuelist[0].splitlines()]
- except ValueError:
- raise ValueError(self.gettext('Not a valid integer list'))
- class GeoPtPropertyField(fields.TextField):
- def process_formdata(self, valuelist):
- if valuelist:
- try:
- lat, lon = valuelist[0].split(',')
- self.data = '%s,%s' % (decimal.Decimal(lat.strip()), decimal.Decimal(lon.strip()),)
- except (decimal.InvalidOperation, ValueError):
- raise ValueError('Not a valid coordinate location')
|