Changeset 5328 for main/waeup.sirp/trunk/src/waeup/sirp/utils
- Timestamp:
- 29 Jul 2010, 08:07:57 (14 years ago)
- Location:
- main/waeup.sirp/trunk/src/waeup/sirp/utils
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
main/waeup.sirp/trunk/src/waeup/sirp/utils/converters.py
r4920 r5328 1 1 """Converters for zope.schema-based datatypes. 2 2 """ 3 import datetime 3 4 import grok 4 5 from zope.component import getMultiAdapter … … 8 9 except ImportError: 9 10 from zope.browser.interfaces import ITerms 10 from zope.schema.interfaces import IBool, IText, IInt, IChoice 11 from zope.schema.interfaces import IBool, IText, IInt, IChoice, IDate 11 12 from waeup.sirp.interfaces import ISchemaTypeConverter 12 13 … … 52 53 53 54 def toString(self, value, strict=True): 55 """Convert given `value` to string according to assigned field type. 56 """ 54 57 if strict: 55 58 self.context.validate(value) … … 131 134 def _convertValueFromString(self, string): 132 135 if self.tokens is not None: 133 return self.tokens[string] 136 result = None 137 try: 138 result = self.tokens[string] 139 except KeyError: 140 # Be gentle... 141 try: 142 result = self.tokens[string.lower()] 143 return result 144 except KeyError: 145 tokenlist = (','.join(self.tokens[:2])) 146 raise ValueError( 147 'The token %s is not valid. Use one of %s, ...' % ( 148 string, tokenlist)) 149 return result 134 150 if self.terms is not None: 135 151 return self.terms.getValue(string) 136 return self.context.source.getTermByToken(string).value 152 result = self.context.source.getTermByToken(string).value 153 return result 137 154 138 155 def _convertValueToString(self, value): … … 164 181 return super(ChoiceConverter, self).toString(value=value, 165 182 strict=strict) 183 184 class DateConverter(Converter): 185 """A converter for zope.schema.IDate fields. 186 187 Converts date to string and vice versa. Stringified dates are 188 expected in format ``YYYY-MM-DD``. 189 190 To support at least some other formats, we accept for conversion 191 from string also the following formats: 192 193 * ``YYYY/MM/DD`` 194 195 * ``DD/MM/YYYY`` 196 197 * ``D/M/YYYY`` 198 199 * ``DD.MM.YYYY`` 200 201 * ``D.M.YYYY`` 202 203 When converting to strings, always 'YYYY-MM-DD' is returned. 204 205 For convenience, when converting from strings also string data 206 separated by space is stripped before processing. Therefore 207 strings like '1990-04-01 12:12:01 GMT +1' will also work. 208 """ 209 grok.context(IDate) 210 grok.provides(ISchemaTypeConverter) 211 212 #: List of supported date formats in `strftime()` notation. 213 formats = ['%Y-%m-%d', '%Y/%m/%d' , '%d/%m/%Y', '%D/%M/%Y', 214 '%d.%m.%Y', '%D.%M.%Y'] 215 216 def _convertValueFromString(self, string): 217 orig_string = string 218 if string is NONE_STRING_VALUE: 219 string = None 220 if string is None: 221 return None 222 value = None 223 if ' ' in string: 224 string = string.split(' ')[0] 225 for format in self.formats: 226 try: 227 value = datetime.datetime.strptime(string, format) 228 break 229 except ValueError: 230 pass 231 if value is None: 232 raise ValueError( 233 'Cannot convert to date: %s. Use YYYY-MM-DD.' % 234 orig_string) 235 value = value.date() 236 return value 237 238 def _convertValueToString(self, value): 239 return datetime.date.strftime(value, '%Y-%m-%d') -
main/waeup.sirp/trunk/src/waeup/sirp/utils/converters.txt
r5140 r5328 267 267 validation checks are disabled with this converter. This speeds 268 268 up things as expensive lookups are avoided. 269 270 271 :class:`DateConverter` 272 ---------------------- 273 274 .. autoclass:: waeup.sirp.utils.converters.DateConverter 275 :members: 276 :inherited-members: 269 277 270 278 … … 682 690 683 691 A more complex (but still realistic example) for conversion of 684 :mod e:`zope.schema.Choice` fields follows. Here we have a special kind692 :mod:`zope.schema.Choice` fields follows. Here we have a special kind 685 693 of object, the `Cave` class, and get their `name` attribute as token. 686 694 … … 739 747 >>> converter.toString(obj2) 740 748 'Fred' 749 750 Date field converters 751 --------------------- 752 753 We create a field that also implements ``IDate``, a regular 754 ``Date`` field: 755 756 >>> from zope.schema import Date 757 >>> from datetime import date 758 >>> field = Date(title=u'Some date', 759 ... default=date(2010, 4, 1), 760 ... required=True) 761 762 Now we can get a converter for this field by explicitly creating a 763 :class:`IntConverter` instance: 764 765 >>> from waeup.sirp.utils.converters import DateConverter 766 >>> converter = DateConverter(field) 767 768 Or we can just grab a registered adapter: 769 770 >>> from waeup.sirp.interfaces import ISchemaTypeConverter 771 >>> converter = ISchemaTypeConverter(field) 772 773 This will select the correct converter for us automatically. 774 775 >>> converter 776 <waeup.sirp.utils.converters.DateConverter object at 0x...> 777 778 Now we can convert strings to this type: 779 780 >>> converter.fromString('2007-04-23') 781 datetime.date(2007, 4, 23) 782 783 And back: 784 785 >>> converter.toString(date(2007,4,23)) 786 '2007-04-23' 787 788 As string input we also accept 'DD/MM/YYYY': 789 790 >>> converter.fromString('13/05/1945') 791 datetime.date(1945, 5, 13) 792 793 and some more bizarre formats: 794 795 >>> converter.fromString('1945/05/13') 796 datetime.date(1945, 5, 13) 797 798 >>> converter.fromString('1945/05/13 12:12:34 GMT+1') 799 datetime.date(1945, 5, 13) 800 801 >>> converter.fromString('1945/5/6') 802 datetime.date(1945, 5, 6) 803 804 >>> converter.fromString('06.05.1945') 805 datetime.date(1945, 5, 6) 806 807 >>> converter.fromString('6.5.1945') 808 datetime.date(1945, 5, 6) 809 810 while other date formats will mean trouble: 811 812 >>> converter.fromString('first of July 1960') 813 Traceback (most recent call last): 814 ... 815 ValueError: Cannot convert to date: first of July 1960. Use YYYY-MM-DD. 816 817 Okay, not very surprising. But the field definitions can help also 818 deliver values, if the given value is missing: 819 820 >>> converter.fromString(None) 821 datetime.date(2010, 4, 1) 822 823 ``None`` is not an acceptable value for fields which are required but 824 provide no default: 825 826 >>> field = Date(title=u'Some Title', 827 ... required=True) 828 >>> converter = ISchemaTypeConverter(field) 829 >>> converter.fromString(None) 830 Traceback (most recent call last): 831 ... 832 RequiredMissing 833 834 If we want to avoid this type of exception (and risk non-applicable 835 data to be stored), we can use the ``strict`` parameter of 836 ``fromString()``: 837 838 >>> converter.fromString(None, strict=False) is None 839 True 840 841 The same for the inverse operation: 842 843 >>> converter.toString(None) 844 Traceback (most recent call last): 845 ... 846 RequiredMissing 847 >>> converter.toString(None, strict=False) is None 848 True 849 850 851 If a field is not required, we will get the ``missing_value`` type in 852 same case: 853 854 >>> field = Date(title=u'Some Title', 855 ... required=False) 856 >>> converter = ISchemaTypeConverter(field) 857 >>> converter.fromString(None) is None 858 True 859 860 >>> converter.toString(None) is None 861 True
Note: See TracChangeset for help on using the changeset viewer.