Browse Source

Modified EmField and Model to fit with the new fieldtypes

Yann Weber 9 years ago
parent
commit
b521c2c7b6

+ 11
- 35
EditorialModel/fields.py View File

5
 
5
 
6
 from EditorialModel.components import EmComponent
6
 from EditorialModel.components import EmComponent
7
 from EditorialModel.exceptions import EmComponentCheckError
7
 from EditorialModel.exceptions import EmComponentCheckError
8
+from EditorialModel.fieldtypes.generic import GenericFieldType
8
 import EditorialModel
9
 import EditorialModel
9
 import EditorialModel.fieldtypes
10
 import EditorialModel.fieldtypes
10
 #from django.db import models
11
 #from django.db import models
17
 
18
 
18
     ranked_in = 'fieldgroup_id'
19
     ranked_in = 'fieldgroup_id'
19
 
20
 
20
-    ftype = None
21
-    help = 'Default help text'
22
-
23
     ## Instanciate a new EmField
21
     ## Instanciate a new EmField
24
     # @todo define and test type for icon and fieldtype
22
     # @todo define and test type for icon and fieldtype
25
     # @warning nullable == True by default
23
     # @warning nullable == True by default
26
     def __init__(self, model, uid, name, fieldgroup_id, fieldtype, optional=False, internal=False, rel_field_id=None, icon='0', string=None, help_text=None, date_update=None, date_create=None, rank=None, nullable=True, default=None, uniq=False, **kwargs):
24
     def __init__(self, model, uid, name, fieldgroup_id, fieldtype, optional=False, internal=False, rel_field_id=None, icon='0', string=None, help_text=None, date_update=None, date_create=None, rank=None, nullable=True, default=None, uniq=False, **kwargs):
27
 
25
 
28
-        if self.ftype is None:
29
-            raise NotImplementedError("Trying to instanciate an EmField and not one of the fieldtypes child classes")
30
-
31
         self.fieldgroup_id = fieldgroup_id
26
         self.fieldgroup_id = fieldgroup_id
32
         self.check_type('fieldgroup_id', int)
27
         self.check_type('fieldgroup_id', int)
33
         self.optional = optional
28
         self.optional = optional
39
         self.icon = icon
34
         self.icon = icon
40
 
35
 
41
         #Field type elements
36
         #Field type elements
37
+        self._fieldtype_cls = GenericFieldType.from_name(fieldtype)
38
+
42
         self.fieldtype = fieldtype
39
         self.fieldtype = fieldtype
40
+        self._fieldtype_args = kwargs
41
+        self._fieldtype_args.update({'nullable' : nullable, 'default' : default, 'uniq' : uniq})
42
+        self._fieldtype_instance = self._fieldtype_cls(**self._fieldtype_args)
43
+
44
+
43
         self.nullable = nullable
45
         self.nullable = nullable
44
         self.default = default
46
         self.default = default
45
         self.uniq = uniq
47
         self.uniq = uniq
46
-
47
-        if len(kwargs) > 0:
48
-            for kwargs_f in kwargs:
49
-                warnings.warn("Argument '%s' not used and will be invalid for EmField __init__" % kwargs_f, SyntaxWarning)
48
+ 
49
+        for kname, kval in kwargs.items():
50
+            setattr(self, kname, kval)
50
 
51
 
51
         super(EmField, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
52
         super(EmField, self).__init__(model=model, uid=uid, name=name, string=string, help_text=help_text, date_update=date_update, date_create=date_create, rank=rank)
52
 
53
 
53
-    @staticmethod
54
-    ## @brief Return an EmField subclass given a wanted field type
55
-    # @return An EmField subclass
56
-    # @throw When not found
57
-    # @see EmField::fieldtypes()
58
-    def get_field_class(ftype, **kwargs):
59
-        if ftype == 'integer':
60
-            ftype_module = importlib.import_module('EditorialModel.fieldtypes.int')
61
-        else:
62
-            ftype_module = importlib.import_module('EditorialModel.fieldtypes.%s' % ftype)
63
-
64
-        return ftype_module.fclass
65
-
66
     @staticmethod
54
     @staticmethod
67
     ## @brief Return the list of allowed field type
55
     ## @brief Return the list of allowed field type
68
     def fieldtypes_list():
56
     def fieldtypes_list():
69
         return [f for f in EditorialModel.fieldtypes.__all__ if f != '__init__']
57
         return [f for f in EditorialModel.fieldtypes.__all__ if f != '__init__']
70
 
58
 
71
-    ## @brief Abstract method that should return a validation function
72
-    # @param raise_e Exception : if not valid raise this exception
73
-    # @param ret_valid : if valid return this value
74
-    # @param ret_invalid : if not valid return this value
75
-    def validation_function(self, raise_e=None, ret_valid=None, ret_invalid=None):
76
-        if self.__class__ == EmField:
77
-            raise NotImplementedError("Abstract method")
78
-        if raise_e is None and ret_valid is None:
79
-            raise AttributeError("Behavior doesn't allows to return a valid validation function")
80
-
81
-        return False
82
-
83
     ## @brief Return the list of relation fields for a rel_to_type
59
     ## @brief Return the list of relation fields for a rel_to_type
84
     # @return None if the field is not a rel_to_type else return a list of EmField
60
     # @return None if the field is not a rel_to_type else return a list of EmField
85
     def rel_to_type_fields(self):
61
     def rel_to_type_fields(self):

+ 2
- 2
EditorialModel/fieldtypes/bool.py View File

2
 
2
 
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4
 
4
 
5
-class EmFieldBool(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6
 
6
 
7
     help = 'A basic boolean field'
7
     help = 'A basic boolean field'
8
 
8
 
9
     ## @brief A char field
9
     ## @brief A char field
10
     # @brief max_length int : The maximum length of this field
10
     # @brief max_length int : The maximum length of this field
11
     def __init__(self, **kwargs):
11
     def __init__(self, **kwargs):
12
-        super(EmFieldBool, self).__init__(ftype='bool',**kwargs)
12
+        super(EmFieldType, self).__init__(ftype='bool',**kwargs)
13
 
13
 

+ 2
- 2
EditorialModel/fieldtypes/char.py View File

2
 
2
 
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4
 
4
 
5
-class EmFieldChar(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6
 
6
 
7
     help = 'Basic string (varchar) field. Take max_length=64 as option'
7
     help = 'Basic string (varchar) field. Take max_length=64 as option'
8
 
8
 
10
     # @brief max_length int : The maximum length of this field
10
     # @brief max_length int : The maximum length of this field
11
     def __init__(self, max_length=64, **kwargs):
11
     def __init__(self, max_length=64, **kwargs):
12
         self.max_length = max_length
12
         self.max_length = max_length
13
-        super(EmFieldChar, self).__init__(ftype = 'char', **kwargs)
13
+        super(EmFieldType, self).__init__(ftype = 'char', **kwargs)
14
 
14
 

+ 3
- 3
EditorialModel/fieldtypes/datetime.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
-from EditorialModel.fields import EmField
3
+from EditorialModel.fieldtypes import GenericFieldType
4
 
4
 
5
 
5
 
6
-class EmFieldDatetime(EmField):
6
+class EmFieldType(GenericFieldType):
7
 
7
 
8
     help = 'A datetime field. Take two boolean options now_on_update and now_on_create'
8
     help = 'A datetime field. Take two boolean options now_on_update and now_on_create'
9
 
9
 
13
     def __init__(self, now_on_update=False, now_on_create=False, **kwargs):
13
     def __init__(self, now_on_update=False, now_on_create=False, **kwargs):
14
         self.now_on_update = now_on_update
14
         self.now_on_update = now_on_update
15
         self.now_on_create = now_on_create
15
         self.now_on_create = now_on_create
16
-        super(EmFieldDatetime, self).__init__(ftype='datetime',**kwargs)
16
+        super(EmFieldType, self).__init__(ftype='datetime',**kwargs)
17
 
17
 

+ 3
- 3
EditorialModel/fieldtypes/file.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
-from EditorialModel.fields import EmField
3
+from EditorialModel.fieldtypes import GenericFieldType
4
 
4
 
5
 
5
 
6
-class EmFieldFile(EmField):
6
+class EmFieldType(GenericFieldType):
7
 
7
 
8
     help = 'A file field. With one options upload_path'
8
     help = 'A file field. With one options upload_path'
9
 
9
 
11
     # @brief max_length int : The maximum length of this field
11
     # @brief max_length int : The maximum length of this field
12
     def __init__(self, upload_path=None, **kwargs):
12
     def __init__(self, upload_path=None, **kwargs):
13
         self.upload_path = upload_path
13
         self.upload_path = upload_path
14
-        super(EmFieldFile, self).__init__(ftype='char',**kwargs)
14
+        super(EmFieldType, self).__init__(ftype='char',**kwargs)
15
 
15
 

+ 13
- 2
EditorialModel/fieldtypes/generic.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
 import types
3
 import types
4
+import importlib
4
 
5
 
5
 ## @brief Abstract class representing a fieldtype
6
 ## @brief Abstract class representing a fieldtype
6
 class GenericFieldType(object):
7
 class GenericFieldType(object):
19
     # @throw NotImplementedError if called directly
20
     # @throw NotImplementedError if called directly
20
     # @throw AttributeError if bad ftype
21
     # @throw AttributeError if bad ftype
21
     # @throw AttributeError if bad check_function
22
     # @throw AttributeError if bad check_function
22
-    def __init__(self, ftype, default = None, nullable = False, check_function = None, **kwargs):
23
+    def __init__(self, ftype, default = None, nullable = True, check_function = None, uniq = False, **kwargs):
23
         if self.__class__ == GenericFieldType:
24
         if self.__class__ == GenericFieldType:
24
             raise NotImplementedError("Abstract class")
25
             raise NotImplementedError("Abstract class")
25
         
26
         
33
 
34
 
34
         self.ftype = ftype
35
         self.ftype = ftype
35
         self.check_function = check_function
36
         self.check_function = check_function
36
-        self.nullalble = bool(nullable)
37
+        self.nullable = bool(nullable)
38
+        self.uniq = bool(uniq)
37
 
39
 
38
         self.check_or_raise(default)
40
         self.check_or_raise(default)
39
         self.default = default
41
         self.default = default
47
     @staticmethod
49
     @staticmethod
48
     def dummy_check(value):
50
     def dummy_check(value):
49
         pass
51
         pass
52
+
53
+    ## @brief Given a fieldtype name return the associated python class
54
+    # @return An GenericFieldType derivated class
55
+    @staticmethod
56
+    def from_name(name):
57
+        module_name = 'EditorialModel.fieldtypes.%s'%(name)
58
+        mod = importlib.import_module(module_name)
59
+        return mod.EmFieldType
60
+
50
     
61
     
51
     ## @brief Transform a value into a valid python representation according to the fieldtype
62
     ## @brief Transform a value into a valid python representation according to the fieldtype
52
     # @param value ? : The value to cast
63
     # @param value ? : The value to cast

+ 0
- 13
EditorialModel/fieldtypes/int.py View File

1
-#-*- coding: utf-8 -*-
2
-
3
-from EditorialModel.fieldtypes import GenericFieldType
4
-
5
-
6
-class EmFieldInt(GenericFieldType):
7
-
8
-    help = 'Basic integer field'
9
-
10
-    def __init__(self, **kwargs):
11
-        super(EmFieldInt, self).__init__(ftype='int',**kwargs)
12
-
13
-fclass = EmFieldInt

+ 11
- 0
EditorialModel/fieldtypes/integer.py View File

1
+#-*- coding: utf-8 -*-
2
+
3
+from EditorialModel.fieldtypes.generic import GenericFieldType
4
+
5
+
6
+class EmFieldType(GenericFieldType):
7
+
8
+    help = 'Basic integer field'
9
+
10
+    def __init__(self, **kwargs):
11
+        super(EmFieldType, self).__init__(ftype='int',**kwargs)

+ 3
- 4
EditorialModel/fieldtypes/regexchar.py View File

1
 #-*- coding: utf-8 -*-
1
 #-*- coding: utf-8 -*-
2
 
2
 
3
 import re
3
 import re
4
-from EditorialModel.fieldtypes.generic import GenericFieldType
4
+import EditorialModel.fieldtypes.char.EmFieldType
5
 
5
 
6
-
7
-class EmFieldCharRegex(EmFieldChar):
6
+class EmFieldType(EditorialModel.fieldtypes.char.EmFieldType):
8
 
7
 
9
     help = 'String field validated with a regex. Take two optionss : max_length and regex'
8
     help = 'String field validated with a regex. Take two optionss : max_length and regex'
10
 
9
 
18
         def re_match(value):
17
         def re_match(value):
19
             if not v_re.match(regex, value):
18
             if not v_re.match(regex, value):
20
                 raise TypeError('"%s" don\'t match the regex "%s"'%(value, regex))
19
                 raise TypeError('"%s" don\'t match the regex "%s"'%(value, regex))
21
-        super(EmFieldCharRegex, self).__init__(check_function=re_match,**kwargs)
20
+        super(EmFieldType, self).__init__(check_function=re_match,**kwargs)
22
 
21
 

+ 2
- 2
EditorialModel/fieldtypes/rel2type.py View File

2
 
2
 
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4
 
4
 
5
-class EmFieldRel2Type(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6
 
6
 
7
     help = 'Relationnal field (relation2type). Take rel_to_type_id as option (an EmType uid)'
7
     help = 'Relationnal field (relation2type). Take rel_to_type_id as option (an EmType uid)'
8
 
8
 
9
     def __init__(self, rel_to_type_id, **kwargs):
9
     def __init__(self, rel_to_type_id, **kwargs):
10
         self.rel_to_type_id = rel_to_type_id
10
         self.rel_to_type_id = rel_to_type_id
11
-        super(EmFieldRel2Type, self).__init__(ftype='rel2type',**kwargs)
11
+        super(EmFieldType, self).__init__(ftype='rel2type',**kwargs)
12
 
12
 
13
     def get_related_type(self):
13
     def get_related_type(self):
14
         return self.model.component(self.rel_to_type_id)
14
         return self.model.component(self.rel_to_type_id)

+ 2
- 2
EditorialModel/fieldtypes/text.py View File

2
 
2
 
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4
 
4
 
5
-class EmFieldText(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6
 
6
 
7
     help = 'A text field (big string)'
7
     help = 'A text field (big string)'
8
 
8
 
9
     def __init__(self, **kwargs):
9
     def __init__(self, **kwargs):
10
-        super(EmFieldText, self).__init__(ftype='text',**kwargs)
10
+        super(EmFieldType, self).__init__(ftype='text',**kwargs)
11
 
11
 

+ 2
- 16
EditorialModel/model.py View File

58
 
58
 
59
     @staticmethod
59
     @staticmethod
60
     ## Given a python class return a name
60
     ## Given a python class return a name
61
-    # @param cls : The python class we want the name
61
+    # @param em_class : The python class we want the name
62
     # @return A class name as string or False if cls is not an EmComponent child class
62
     # @return A class name as string or False if cls is not an EmComponent child class
63
-    # @todo réécrire le split, c'est pas bô
64
     def name_from_emclass(em_class):
63
     def name_from_emclass(em_class):
65
         if em_class not in Model.components_class:
64
         if em_class not in Model.components_class:
66
-            if issubclass(em_class, EmField):
67
-                return 'EmField'
68
             return False
65
             return False
69
         return em_class.__name__
66
         return em_class.__name__
70
 
67
 
80
             cls_name = kwargs['component']
77
             cls_name = kwargs['component']
81
             del kwargs['component']
78
             del kwargs['component']
82
 
79
 
83
-            if cls_name == 'EmField':
84
-                #Special EmField process because of fieldtypes
85
-                if not 'fieldtype' in kwargs:
86
-                    raise AttributeError("Missing 'fieldtype' from EmField instanciation")
87
-                cls = EditorialModel.fields.EmField.get_field_class(kwargs['fieldtype'])
88
-            else:
89
-                cls = self.emclass_from_name(cls_name)
80
+            cls = self.emclass_from_name(cls_name)
90
 
81
 
91
             if cls:
82
             if cls:
92
                 kwargs['uid'] = uid
83
                 kwargs['uid'] = uid
160
         
151
         
161
         if component_type not in [ n for n in self._components.keys() if n != 'uids' ]:
152
         if component_type not in [ n for n in self._components.keys() if n != 'uids' ]:
162
             raise ValueError("Invalid component_type rpovided")
153
             raise ValueError("Invalid component_type rpovided")
163
-        elif component_type == 'EmField':
164
-            #special process for EmField
165
-            if not 'fieldtype' in datas:
166
-                raise AttributeError("Missing 'fieldtype' from EmField instanciation")
167
-            em_obj = EditorialModel.fields.EmField.get_field_class(datas['fieldtype'])
168
         else:
154
         else:
169
             em_obj = self.emclass_from_name(component_type)
155
             em_obj = self.emclass_from_name(component_type)
170
 
156
 

+ 3
- 5
EditorialModel/test/test_model.py View File

6
 from EditorialModel.types import EmType
6
 from EditorialModel.types import EmType
7
 from EditorialModel.fieldgroups import EmFieldGroup
7
 from EditorialModel.fieldgroups import EmFieldGroup
8
 from EditorialModel.fields import EmField
8
 from EditorialModel.fields import EmField
9
-from EditorialModel.fieldtypes.char import EmFieldChar
10
 from EditorialModel.components import EmComponent
9
 from EditorialModel.components import EmComponent
11
 from Lodel.utils.mlstring import MlString
10
 from Lodel.utils.mlstring import MlString
12
 
11
 
13
 
12
 
14
 from EditorialModel.backend.json_backend import EmBackendJson
13
 from EditorialModel.backend.json_backend import EmBackendJson
15
 from EditorialModel.backend.dummy_backend import EmBackendDummy
14
 from EditorialModel.backend.dummy_backend import EmBackendDummy
16
-from EditorialModel.migrationhandler.django import DjangoMigrationHandler
17
 from EditorialModel.migrationhandler.dummy import DummyMigrationHandler
15
 from EditorialModel.migrationhandler.dummy import DummyMigrationHandler
18
 
16
 
19
 
17
 
27
         model = Model(EmBackendJson('EditorialModel/test/me.json'))
25
         model = Model(EmBackendJson('EditorialModel/test/me.json'))
28
         self.assertTrue(isinstance(model, Model))
26
         self.assertTrue(isinstance(model, Model))
29
 
27
 
30
-        model = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DjangoMigrationHandler('LodelTestInstance', debug=False, dryrun=True))
28
+        model = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DummyMigrationHandler('LodelTestInstance'))
31
         self.assertTrue(isinstance(model, Model))
29
         self.assertTrue(isinstance(model, Model))
32
 
30
 
33
     def test_bad_init(self):
31
     def test_bad_init(self):
149
                 },
147
                 },
150
             },
148
             },
151
             'EmField': {
149
             'EmField': {
152
-                'cls': EmFieldChar,
150
+                'cls': EmField,
153
                 'cdats': {
151
                 'cdats': {
154
                     'name': 'FooField',
152
                     'name': 'FooField',
155
                     'fieldgroup_id': self.ed_mod.components(EmFieldGroup)[0].uid,
153
                     'fieldgroup_id': self.ed_mod.components(EmFieldGroup)[0].uid,
288
     def test_hash(self):
286
     def test_hash(self):
289
         """ Test that __hash__ and __eq__ work properly on models """
287
         """ Test that __hash__ and __eq__ work properly on models """
290
         me1 = Model(EmBackendJson('EditorialModel/test/me.json'))
288
         me1 = Model(EmBackendJson('EditorialModel/test/me.json'))
291
-        me2 = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DjangoMigrationHandler('LodelTestInstance', debug=False, dryrun=True))
289
+        me2 = Model(EmBackendJson('EditorialModel/test/me.json'), migration_handler=DummyMigrationHandler('LodelTestInstance'))
292
 
290
 
293
         self.assertEqual(hash(me1), hash(me2), "When instanciate from the same backend & file but with another migration handler the hashes differs")
291
         self.assertEqual(hash(me1), hash(me2), "When instanciate from the same backend & file but with another migration handler the hashes differs")
294
         self.assertTrue(me1.__eq__(me2))
292
         self.assertTrue(me1.__eq__(me2))

Loading…
Cancel
Save