|
@@ -1,494 +0,0 @@
|
1
|
|
-#-*- coding: utf-8 -*-
|
2
|
|
-
|
3
|
|
-from django.db import models
|
4
|
|
-import re
|
5
|
|
-import datetime
|
6
|
|
-import json
|
7
|
|
-import importlib
|
8
|
|
-import copy
|
9
|
|
-import EditorialModel
|
10
|
|
-from Lodel.utils.mlstring import MlString
|
11
|
|
-
|
12
|
|
-
|
13
|
|
-## @brief Characterise fields for LeObject and EmComponent
|
14
|
|
-# This class handles values rules for LeObject and EmComponents.
|
15
|
|
-#
|
16
|
|
-# It allows to EmFieldValue classes family to have rules to cast, validate and save values.
|
17
|
|
-#
|
18
|
|
-# There is exposed methods that allows LeObject and EmType to run a save sequence. This methods are :
|
19
|
|
-# - EmFieldType.to_value() That cast a value to an EmFieldType internal storage
|
20
|
|
-# - EmFieldType.is_valid() That indicates wether or not a value is valid
|
21
|
|
-# - EmFieldType.pre_save() That returns weighted SQL request that must be run before any value save @ref EditorialModel::types::EmType.save_values()
|
22
|
|
-# - EmFieldType.to_sql() That returns a value that can be inserted in database.
|
23
|
|
-# - EmFieldType.post_save() That returns weighted SQL request that must be run after any value save @ref EditorialModel::types::EmType.save_values()
|
24
|
|
-#
|
25
|
|
-class EmFieldType(object):
|
26
|
|
-
|
27
|
|
- ## Stores options and default value for EmFieldType
|
28
|
|
- # options list :
|
29
|
|
- # - type (str|None) : if None will make an 'abstract' fieldtype (with no value assignement possible)
|
30
|
|
- # - nullable (bool) : tell whether or not a fieldType accept NULL value
|
31
|
|
- # - default (mixed) : The default value for a FieldType
|
32
|
|
- # - primarykey (bool) : If true the fieldType represent a PK
|
33
|
|
- # - autoincrement (bool) : If true the fieldType will be autoincremented
|
34
|
|
- # - index (bool) : If true the columns will be indexed in Db
|
35
|
|
- # - name (str) : FieldType name
|
36
|
|
- # - doc (str) : FieldType documentation
|
37
|
|
- # - onupdate (callable) : A callback to call on_update
|
38
|
|
- # - valueobject (EmFieldValue or childs) : An object that represent values for this fieldType
|
39
|
|
- # - type_* (mixed) : Use to construct an options dictinnary for a type (exemple : type_length => nnewColumn(lenght= [type_lenght VALUE] )) @ref EmFieldSQLType
|
40
|
|
- # - validators (list) : List of validator functions to use
|
41
|
|
- _opt = {
|
42
|
|
- 'name': None,
|
43
|
|
- 'type': None,
|
44
|
|
- 'nullable': True,
|
45
|
|
- 'default': None,
|
46
|
|
- 'primarykey': False,
|
47
|
|
- 'autoincrement': False,
|
48
|
|
- 'uniq': False,
|
49
|
|
- 'index': False,
|
50
|
|
- 'doc': None,
|
51
|
|
- 'onupdate': None,
|
52
|
|
- 'valueobject': None,
|
53
|
|
- 'validators': None
|
54
|
|
- }
|
55
|
|
-
|
56
|
|
- ## Instanciate an EmFieldType
|
57
|
|
- # For arguments see @ref EmFieldType::_opt
|
58
|
|
- # @see EmFieldType::_opt
|
59
|
|
- def __init__(self, **kwargs):
|
60
|
|
- self.__init(kwargs)
|
61
|
|
- self.type_options = dict()
|
62
|
|
-
|
63
|
|
- # stores all col_* arguments into the self.type_options dictionary
|
64
|
|
- args = kwargs.copy()
|
65
|
|
- for optname in args:
|
66
|
|
- type_opt = re.sub(r'^type_', '', optname)
|
67
|
|
- if type_opt != optname:
|
68
|
|
- self.type_options[type_opt] = args[optname]
|
69
|
|
- del kwargs[optname]
|
70
|
|
-
|
71
|
|
- # checks if the other arguments are valid
|
72
|
|
- if len(set(kwargs.keys()) - set(self.__class__._opt.keys())) > 0:
|
73
|
|
- badargs = ""
|
74
|
|
- for bad in set(kwargs.keys()) - set(self.__class__._opt.keys()):
|
75
|
|
- badargs += " " + bad
|
76
|
|
- raise TypeError("Unexpected arguments : %s" % badargs)
|
77
|
|
-
|
78
|
|
- # stores other arguments as instance attribute
|
79
|
|
- for opt_name in self.__class__._opt:
|
80
|
|
- setattr(self, opt_name, (kwargs[opt_name] if opt_name in kwargs else self.__class__._opt[opt_name]))
|
81
|
|
-
|
82
|
|
- # checks type's options valididty
|
83
|
|
- if self.type != None:
|
84
|
|
- try:
|
85
|
|
- EmFieldSQLType.sqlType(self.type, **self.type_options)
|
86
|
|
- except TypeError as e:
|
87
|
|
- raise e
|
88
|
|
-
|
89
|
|
- # Default value for name
|
90
|
|
- if self.name == None:
|
91
|
|
- if self.__class__ == EmFieldType:
|
92
|
|
- self.name = 'generic'
|
93
|
|
- else:
|
94
|
|
- self.name = self.__class__.__name__
|
95
|
|
-
|
96
|
|
- # Default value for doc
|
97
|
|
- if self.doc == None:
|
98
|
|
- if self.__class__ == EmFieldType:
|
99
|
|
- self.doc = 'Abstract generic EmFieldType'
|
100
|
|
- else:
|
101
|
|
- self.doc = self.__class__.__name__
|
102
|
|
-
|
103
|
|
- ## MUST be called first in each constructor
|
104
|
|
- # @todo this solution is not good (look at the __init__ for EmFieldType childs)
|
105
|
|
- def __init(self, kwargs):
|
106
|
|
- try:
|
107
|
|
- self.args_copy
|
108
|
|
- except AttributeError:
|
109
|
|
- self.args_copy = kwargs.copy()
|
110
|
|
-
|
111
|
|
- @property
|
112
|
|
- ## A predicate that indicates whether or not an EmFieldType is "abstract"
|
113
|
|
- def is_abstract(self):
|
114
|
|
- return (self.type == None)
|
115
|
|
-
|
116
|
|
- ## Returns a copy of the current EmFieldType
|
117
|
|
- def copy(self):
|
118
|
|
- args = self.args_copy.copy()
|
119
|
|
- return self.__class__(**args)
|
120
|
|
-
|
121
|
|
- def dump_opt(self):
|
122
|
|
- return json.dumps(self.args_copy)
|
123
|
|
-
|
124
|
|
- @staticmethod
|
125
|
|
- ## Return an instance from a classname and options from dump_opt
|
126
|
|
- # @param classname str: The EmFieldType class name
|
127
|
|
- # @param json_opt str: getted from dump_opt
|
128
|
|
- def restore(colname, classname, json_opt):
|
129
|
|
- field_type_class = getattr(EditorialModel.fieldtypes, classname)
|
130
|
|
- init_opt = json.loads(json_opt)
|
131
|
|
- init_opt['name'] = colname
|
132
|
|
- return field_type_class(**init_opt)
|
133
|
|
-
|
134
|
|
- ## Return a value object 'driven' by this EmFieldType
|
135
|
|
- # @param name str: The column name associated with the value
|
136
|
|
- # @param *init_val mixed: If given this will be the initialisation value
|
137
|
|
- # @return a EmFieldValue instance
|
138
|
|
- # @todo better default value (and bad values) handling
|
139
|
|
- def valueObject(self, name, *init_val):
|
140
|
|
- if self.valueObject == None:
|
141
|
|
- return EmFieldValue(name, self, *init_val)
|
142
|
|
- return self.valueObject(name, self, *init_val)
|
143
|
|
-
|
144
|
|
- ## Cast to the correct value
|
145
|
|
- # @param v mixed : the value to cast
|
146
|
|
- # @return A gently casted value
|
147
|
|
- # @throw ValueError if v is innapropriate
|
148
|
|
- # @throw NotImplementedError if self is an abstract EmFieldType
|
149
|
|
- def to_value(self, v):
|
150
|
|
- if self.type == None:
|
151
|
|
- raise NotImplemented("This EmFieldType is abstract")
|
152
|
|
- if v == None and not self.nullable:
|
153
|
|
- raise TypeError("Field not nullable")
|
154
|
|
- return v
|
155
|
|
-
|
156
|
|
- ## to_value alias
|
157
|
|
- # @param value mixed : the value to cast
|
158
|
|
- # @return A casted value
|
159
|
|
- def from_string(self, value):
|
160
|
|
- return self.to_value(value)
|
161
|
|
-
|
162
|
|
- ## Returns a gently sql forged value
|
163
|
|
- # @return A sql forged value
|
164
|
|
- # @warning It assumes that the value is correct and comes from an EmFieldValue object
|
165
|
|
- def to_sql(self, value):
|
166
|
|
- if self.is_abstract:
|
167
|
|
- raise NotImplementedError("This EmFieldType is abstract")
|
168
|
|
- return True
|
169
|
|
-
|
170
|
|
- ## Returns whether or not a value is valid for this EmFieldType
|
171
|
|
- # @note This function always returns True and is here for being overloaded by child objects
|
172
|
|
- # @return A boolean, True if valid else False
|
173
|
|
- def is_valid(self, value):
|
174
|
|
- if self.is_abstract:
|
175
|
|
- raise NotImplementedError("This EmFieldType is abstract")
|
176
|
|
- return True
|
177
|
|
-
|
178
|
|
- ## Pre-save actions
|
179
|
|
- def pre_save(self):
|
180
|
|
- if self.is_abstract:
|
181
|
|
- raise NotImplementedError("This EmFieldType is abstract")
|
182
|
|
- return []
|
183
|
|
-
|
184
|
|
- ## Post-save actions
|
185
|
|
- def post_save(self):
|
186
|
|
- if self.is_abstract:
|
187
|
|
- raise NotImplementedError("This EmFieldType is abstract")
|
188
|
|
- return []
|
189
|
|
-
|
190
|
|
- @classmethod
|
191
|
|
- ## Function designed to be called by child class to enforce a type
|
192
|
|
- # @param args dict: The kwargs argument of __init__
|
193
|
|
- # @param typename str: The typename to enforce
|
194
|
|
- # @return The new kwargs to be used
|
195
|
|
- # @throw TypeError if type is present is args
|
196
|
|
- def _setType(cl, args, typename):
|
197
|
|
- return cl._argEnforce(args, 'type', typename, True)
|
198
|
|
-
|
199
|
|
- @classmethod
|
200
|
|
- ## Function designed to be called by child's constructo to enforce an argument
|
201
|
|
- # @param args dict: The constructor's kwargs
|
202
|
|
- # @param argname str: The name of the argument to enforce
|
203
|
|
- # @param argval mixed: The value we want to enforce
|
204
|
|
- # @param Return a new kwargs
|
205
|
|
- # @throw TypeError if type is present is args and exception argument is True
|
206
|
|
- def _argEnforce(cl, args, argname, argval, exception=True):
|
207
|
|
- if exception and argname in args:
|
208
|
|
- raise TypeError("Invalid argument '"+argname+"' for "+cl.__class__.__name__+" __init__")
|
209
|
|
- args[argname] = argval
|
210
|
|
- return args
|
211
|
|
-
|
212
|
|
- @classmethod
|
213
|
|
- ## Function designed to be called by child's constructor to set a default value
|
214
|
|
- # @param args dict: The constructor's kwargs
|
215
|
|
- # @param argname str: The name of the argument with default value
|
216
|
|
- # @param argval mixed : The default value
|
217
|
|
- # @return a new kwargs dict
|
218
|
|
- def _argDefault(cl, args, argname, argval):
|
219
|
|
- if argname not in args:
|
220
|
|
- args[argname] = argval
|
221
|
|
- return args
|
222
|
|
-
|
223
|
|
-class EmFieldValue(object):
|
224
|
|
-
|
225
|
|
- ## Instanciates a EmFieldValue
|
226
|
|
- # @param name str : The column name associated with this value
|
227
|
|
- # @param fieldtype EmFieldType: The EmFieldType defining the value
|
228
|
|
- # @param *value *list: This argument allow to pass a value to set (even None) and to detect if no value given to set to EmFieldType's default value
|
229
|
|
- # @throw TypeError if more than 2 arguments given
|
230
|
|
- # @throw TypeError if fieldtype is not an EmFieldType
|
231
|
|
- # @throw TypeError if fieldtype is an abstract EmFieldType
|
232
|
|
- def __init__(self, name, fieldtype, *value):
|
233
|
|
- if not isinstance(fieldtype, EmFieldType):
|
234
|
|
- raise TypeError("Expected <class EmFieldType> for 'fieldtype' argument, but got : %s instead" % str(type(fieldtype)))
|
235
|
|
- if fieldtype.is_abstract:
|
236
|
|
- raise TypeError("The given fieldtype in argument is abstract.")
|
237
|
|
-
|
238
|
|
- # This copy ensures that the fieldtype will not change during the value lifecycle
|
239
|
|
- super(EmFieldValue, self).__setattr__('fieldtype', fieldtype.copy())
|
240
|
|
-
|
241
|
|
- if len(value) > 1:
|
242
|
|
- raise TypeError("Accept only 2 positionnal parameters. %s given." % str(len(value)+1))
|
243
|
|
- elif len(value) == 1:
|
244
|
|
- self.value = value[0]
|
245
|
|
- else:
|
246
|
|
- self.value = fieldtype.default
|
247
|
|
-
|
248
|
|
- # Use this to set value in the constructor
|
249
|
|
- setv = super(EmFieldValue, self).__setattr__
|
250
|
|
- # This copy makes column attributes accessible easily
|
251
|
|
- for attrname in self.fieldtype.__dict__:
|
252
|
|
- setv(attrname, getattr(self.fieldtype, attrname))
|
253
|
|
-
|
254
|
|
- # Assign some EmFieldType methods to the value
|
255
|
|
- setv('from_python', self.fieldtype.to_value)
|
256
|
|
- setv('from_string', self.fieldtype.to_value)
|
257
|
|
- #setv('sqlCol', self.fieldtype.sqlCol)
|
258
|
|
-
|
259
|
|
- ## The only writable attribute of EmFieldValue is the value
|
260
|
|
- # @param name str: Have to be value
|
261
|
|
- # @param value mixed: The value to set
|
262
|
|
- # @throw AtrributeError if another attribute than value is to be set
|
263
|
|
- # @throw ValueError if self.to_value raises it
|
264
|
|
- # @see EmFieldType::to_value()
|
265
|
|
- def __setattr__(self, name, value):
|
266
|
|
- if name != "value":
|
267
|
|
- raise AttributeError("EmFieldValue has only the value property settable")
|
268
|
|
- super(EmFieldValue,self).__setattr__('value', self.fieldtype.to_value(value))
|
269
|
|
-
|
270
|
|
- ##
|
271
|
|
- # @warning When getting the fieldtype you actually get a copy of it to prevent any modifications !
|
272
|
|
- def __getattr__(self, name):
|
273
|
|
- if name == 'fieldtype':
|
274
|
|
- return self.fieldtype.copy()
|
275
|
|
- return super(EmFieldValue, self).__getattribute__(name)
|
276
|
|
-
|
277
|
|
- ## @brief Return a valid SQL value
|
278
|
|
- #
|
279
|
|
- # Can be used to convert any value (giving one positionnal argument) or to return the current value
|
280
|
|
- # @param *value list: If a positionnal argument is given return it and not the instance value
|
281
|
|
- # @return A value suitable for sql
|
282
|
|
- def to_sql(self, *value):
|
283
|
|
- if len(value) > 1:
|
284
|
|
- raise TypeError("Excepted 0 or 1 positional argument but got "+str(len(value)))
|
285
|
|
- elif len(value) == 1:
|
286
|
|
- return self.fieldtype.to_sql(value[0])
|
287
|
|
- return self.fieldtype.to_sql(self.value)
|
288
|
|
-
|
289
|
|
-class EmFieldSQLType(object):
|
290
|
|
- _integer = {'sql': models.IntegerField}
|
291
|
|
- _bigint = {'sql': models.BigIntegerField}
|
292
|
|
- _smallint = {'sql': models.SmallIntegerField}
|
293
|
|
- _boolean = {'sql': models.BooleanField}
|
294
|
|
- _nullableboolean = {'sql': models.NullBooleanField}
|
295
|
|
- _float = {'sql': models.FloatField}
|
296
|
|
- _varchar = {'sql': models.CharField}
|
297
|
|
- _text = {'sql': models.TextField}
|
298
|
|
- _time = {'sql': models.TimeField}
|
299
|
|
- _date = {'sql': models.DateField}
|
300
|
|
- _datetime = {'sql': models.DateTimeField}
|
301
|
|
-
|
302
|
|
- _names = {
|
303
|
|
- 'int': _integer,
|
304
|
|
- 'integer': _integer,
|
305
|
|
- 'bigint': _bigint,
|
306
|
|
- 'smallint': _smallint,
|
307
|
|
- 'boolean': _boolean,
|
308
|
|
- 'bool': _boolean,
|
309
|
|
- 'float': _float,
|
310
|
|
- 'char': _varchar,
|
311
|
|
- 'varchar': _varchar,
|
312
|
|
- 'text': _text,
|
313
|
|
- 'time': _time,
|
314
|
|
- 'date': _date,
|
315
|
|
- 'datetime': _datetime,
|
316
|
|
- }
|
317
|
|
-
|
318
|
|
- @classmethod
|
319
|
|
- def sqlType(cls, name, **kwargs):
|
320
|
|
- if not isinstance(name, str):
|
321
|
|
- raise TypeError("Expect <class str>, <class int>|None but got : %s %s" % (str(type(name)), str(type(size))))
|
322
|
|
- name = name.lower()
|
323
|
|
- if name not in cls._names:
|
324
|
|
- raise ValueError("Unknown type '%s'" % name)
|
325
|
|
-
|
326
|
|
- if name in ['boolean','bool'] and kwargs['nullable'] in [1,'true']:
|
327
|
|
- sqlclass = _nullableboolean
|
328
|
|
- else:
|
329
|
|
- sqlclass = cls._names[name]
|
330
|
|
-
|
331
|
|
- if len(kwargs) == 0:
|
332
|
|
- return sqlclass['sql']
|
333
|
|
-
|
334
|
|
- return sqlclass['sql'](**kwargs)
|
335
|
|
-
|
336
|
|
-
|
337
|
|
-## @brief Represents values with common arithmetic operations
|
338
|
|
-class EmFieldValue_int(EmFieldValue):
|
339
|
|
- def __int__(self):
|
340
|
|
- return self.value
|
341
|
|
-
|
342
|
|
- def __add__(self, other):
|
343
|
|
- return self.value + other
|
344
|
|
-
|
345
|
|
- def __sub__(self, other):
|
346
|
|
- return self.value - other
|
347
|
|
-
|
348
|
|
- def __mul__(self, other):
|
349
|
|
- return self.value * other
|
350
|
|
-
|
351
|
|
- def __div__(self, other):
|
352
|
|
- return self.value / other
|
353
|
|
-
|
354
|
|
- def __mod__(self, other):
|
355
|
|
- return self.value % other
|
356
|
|
-
|
357
|
|
- def __iadd__(self, other):
|
358
|
|
- self.value = int(self.value + other)
|
359
|
|
- return self
|
360
|
|
-
|
361
|
|
- def __isub__(self, other):
|
362
|
|
- self.value = int(self.value - other)
|
363
|
|
- return self
|
364
|
|
-
|
365
|
|
- def __imul__(self, other):
|
366
|
|
- self.value = int(self.value * other)
|
367
|
|
- return self
|
368
|
|
-
|
369
|
|
- def __idiv__(self, other):
|
370
|
|
- self.value = int(self.value / other)
|
371
|
|
- return self
|
372
|
|
-
|
373
|
|
-
|
374
|
|
-## @brief Handles integer fields
|
375
|
|
-# @note Enforcing type to be int
|
376
|
|
-# @note Default name is 'integer' and default 'valueobject' is EmFieldValue_int
|
377
|
|
-class EmField_integer(EmFieldType):
|
378
|
|
-
|
379
|
|
- def __init__(self, **kwargs):
|
380
|
|
- self._init(kwargs)
|
381
|
|
- # Default name
|
382
|
|
- kwargs = self.__class__._argDefault(kwargs, 'name', 'integer')
|
383
|
|
- # Default value object
|
384
|
|
- kwargs = self.__class__._argDefault(kwargs, 'valueobject', EmFieldValue_int)
|
385
|
|
- # Type enforcing
|
386
|
|
- kwargs = self.__class__._setType(kwargs, 'int')
|
387
|
|
- super(EmField_integer, self).__init__(**kwargs)
|
388
|
|
-
|
389
|
|
- ##
|
390
|
|
- # @todo catch cast error ?
|
391
|
|
- #def to_sql(self, value):
|
392
|
|
- # return value
|
393
|
|
-
|
394
|
|
- def to_value(self, value):
|
395
|
|
- if value == None:
|
396
|
|
- return super(EmField_integer, self).to_value(value)
|
397
|
|
- return int(value)
|
398
|
|
-
|
399
|
|
-
|
400
|
|
-## @brief Handles boolean fields
|
401
|
|
-# @note Enforce type to be 'boolean'
|
402
|
|
-# @note Default name is 'boolean'
|
403
|
|
-class EmField_boolean(EmFieldType):
|
404
|
|
- def __init__(self, **kwargs):
|
405
|
|
- self._init(kwargs)
|
406
|
|
- #Default name
|
407
|
|
- kwargs = self.__class__._argDefault(kwargs, 'name', 'boolean')
|
408
|
|
- #Type enforcing
|
409
|
|
- kwargs = self.__class__._setType(kwargs, 'boolean')
|
410
|
|
- super(EmField_boolean, self).__init__(**kwargs)
|
411
|
|
-
|
412
|
|
- #def to_sql(self, value):
|
413
|
|
- # return 1 if super(EmField_boolean, self).to_sql(value) else 0
|
414
|
|
-
|
415
|
|
- def to_value(self, value):
|
416
|
|
- if value == None:
|
417
|
|
- return super(EmField_boolean, self).to_value(value)
|
418
|
|
- self.value = bool(value)
|
419
|
|
- return self.value
|
420
|
|
-
|
421
|
|
-
|
422
|
|
-## @brief Handles string fields
|
423
|
|
-# @note Enforce type to be (varchar)
|
424
|
|
-# @note Default 'name' is 'char'
|
425
|
|
-# @note Default 'type_length' is 76
|
426
|
|
-class EmField_char(EmFieldType):
|
427
|
|
-
|
428
|
|
- default_length = 76
|
429
|
|
-
|
430
|
|
- def __init__(self, **kwargs):
|
431
|
|
- self._init(kwargs)
|
432
|
|
- kwargs = self.__class__._argDefault(kwargs, 'type_length', self.__class__.default_length)
|
433
|
|
- kwargs = self.__class__._argDefault(kwargs, 'name', 'char')
|
434
|
|
- #Type enforcing
|
435
|
|
- kwargs = self.__class__._setType(kwargs, 'varchar')
|
436
|
|
- super(EmField_char, self).__init__(**kwargs)
|
437
|
|
-
|
438
|
|
- #def to_sql(self, value):
|
439
|
|
- # return str(value)
|
440
|
|
-
|
441
|
|
-
|
442
|
|
-## @brief Handles date fields
|
443
|
|
-# @note Enforce type to be 'datetime'
|
444
|
|
-# @todo rename to EmField_datetime
|
445
|
|
-# @todo timezones support
|
446
|
|
-class EmField_date(EmFieldType):
|
447
|
|
- def __init__(self, **kwargs):
|
448
|
|
- self._init(kwargs)
|
449
|
|
- kwargs = self.__class__._argDefault(kwargs, 'name', 'date')
|
450
|
|
- #Type enforcing
|
451
|
|
- kwargs = self.__class__._setType(kwargs, 'datetime')
|
452
|
|
- super(EmField_date, self).__init__(**kwargs)
|
453
|
|
-
|
454
|
|
- #def to_sql(self, value):
|
455
|
|
- # return value #thanks to sqlalchemy
|
456
|
|
-
|
457
|
|
- def to_value(self, value):
|
458
|
|
- if value == None:
|
459
|
|
- return super(EmField_date, self).to_value(value)
|
460
|
|
- if isinstance(value, int):
|
461
|
|
- #assume its a timestamp
|
462
|
|
- return datetime.fromtimestamp(value)
|
463
|
|
- if isinstance(value, datetime.datetime):
|
464
|
|
- return value
|
465
|
|
-
|
466
|
|
-
|
467
|
|
-## @brief Handles strings with translations
|
468
|
|
-class EmField_mlstring(EmField_char):
|
469
|
|
-
|
470
|
|
- def __init__(self, **kwargs):
|
471
|
|
- self._init(kwargs)
|
472
|
|
- kwargs = self.__class__._argDefault(kwargs, 'name', 'mlstr')
|
473
|
|
- super(EmField_mlstring, self).__init__(**kwargs)
|
474
|
|
-
|
475
|
|
- #def to_sql(self, value):
|
476
|
|
- # return value.__str__()
|
477
|
|
-
|
478
|
|
- def to_value(self, value):
|
479
|
|
- if value == None:
|
480
|
|
- return super(EmField_mlstring, self).to_value(value)
|
481
|
|
- if isinstance(value, str):
|
482
|
|
- return MlString.load(value)
|
483
|
|
- elif isinstance(value, MlString):
|
484
|
|
- return value
|
485
|
|
- raise TypeError("<class str> or <class MlString> excepted. But got "+str(type(value)))
|
486
|
|
-
|
487
|
|
-
|
488
|
|
-## @brief Handles lodel uid fields
|
489
|
|
-class EmField_uid(EmField_integer):
|
490
|
|
-
|
491
|
|
- def __init__(self, **kwargs):
|
492
|
|
- self._init(kwargs)
|
493
|
|
- kwargs = self.__class__._argEnforce(kwargs, 'primarykey', True)
|
494
|
|
- super(EmField_uid, self).__init__(**kwargs)
|