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,6 +5,7 @@ import warnings
5 5
 
6 6
 from EditorialModel.components import EmComponent
7 7
 from EditorialModel.exceptions import EmComponentCheckError
8
+from EditorialModel.fieldtypes.generic import GenericFieldType
8 9
 import EditorialModel
9 10
 import EditorialModel.fieldtypes
10 11
 #from django.db import models
@@ -17,17 +18,11 @@ class EmField(EmComponent):
17 18
 
18 19
     ranked_in = 'fieldgroup_id'
19 20
 
20
-    ftype = None
21
-    help = 'Default help text'
22
-
23 21
     ## Instanciate a new EmField
24 22
     # @todo define and test type for icon and fieldtype
25 23
     # @warning nullable == True by default
26 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 26
         self.fieldgroup_id = fieldgroup_id
32 27
         self.check_type('fieldgroup_id', int)
33 28
         self.optional = optional
@@ -39,47 +34,28 @@ class EmField(EmComponent):
39 34
         self.icon = icon
40 35
 
41 36
         #Field type elements
37
+        self._fieldtype_cls = GenericFieldType.from_name(fieldtype)
38
+
42 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 45
         self.nullable = nullable
44 46
         self.default = default
45 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 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 54
     @staticmethod
67 55
     ## @brief Return the list of allowed field type
68 56
     def fieldtypes_list():
69 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 59
     ## @brief Return the list of relation fields for a rel_to_type
84 60
     # @return None if the field is not a rel_to_type else return a list of EmField
85 61
     def rel_to_type_fields(self):

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

@@ -2,12 +2,12 @@
2 2
 
3 3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4 4
 
5
-class EmFieldBool(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6 6
 
7 7
     help = 'A basic boolean field'
8 8
 
9 9
     ## @brief A char field
10 10
     # @brief max_length int : The maximum length of this field
11 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,7 +2,7 @@
2 2
 
3 3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4 4
 
5
-class EmFieldChar(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6 6
 
7 7
     help = 'Basic string (varchar) field. Take max_length=64 as option'
8 8
 
@@ -10,5 +10,5 @@ class EmFieldChar(GenericFieldType):
10 10
     # @brief max_length int : The maximum length of this field
11 11
     def __init__(self, max_length=64, **kwargs):
12 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,9 +1,9 @@
1 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 8
     help = 'A datetime field. Take two boolean options now_on_update and now_on_create'
9 9
 
@@ -13,5 +13,5 @@ class EmFieldDatetime(EmField):
13 13
     def __init__(self, now_on_update=False, now_on_create=False, **kwargs):
14 14
         self.now_on_update = now_on_update
15 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,9 +1,9 @@
1 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 8
     help = 'A file field. With one options upload_path'
9 9
 
@@ -11,5 +11,5 @@ class EmFieldFile(EmField):
11 11
     # @brief max_length int : The maximum length of this field
12 12
     def __init__(self, upload_path=None, **kwargs):
13 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,6 +1,7 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3 3
 import types
4
+import importlib
4 5
 
5 6
 ## @brief Abstract class representing a fieldtype
6 7
 class GenericFieldType(object):
@@ -19,7 +20,7 @@ class GenericFieldType(object):
19 20
     # @throw NotImplementedError if called directly
20 21
     # @throw AttributeError if bad ftype
21 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 24
         if self.__class__ == GenericFieldType:
24 25
             raise NotImplementedError("Abstract class")
25 26
         
@@ -33,7 +34,8 @@ class GenericFieldType(object):
33 34
 
34 35
         self.ftype = ftype
35 36
         self.check_function = check_function
36
-        self.nullalble = bool(nullable)
37
+        self.nullable = bool(nullable)
38
+        self.uniq = bool(uniq)
37 39
 
38 40
         self.check_or_raise(default)
39 41
         self.default = default
@@ -47,6 +49,15 @@ class GenericFieldType(object):
47 49
     @staticmethod
48 50
     def dummy_check(value):
49 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 62
     ## @brief Transform a value into a valid python representation according to the fieldtype
52 63
     # @param value ? : The value to cast

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

@@ -1,13 +0,0 @@
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

@@ -0,0 +1,11 @@
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,10 +1,9 @@
1 1
 #-*- coding: utf-8 -*-
2 2
 
3 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 8
     help = 'String field validated with a regex. Take two optionss : max_length and regex'
10 9
 
@@ -18,5 +17,5 @@ class EmFieldCharRegex(EmFieldChar):
18 17
         def re_match(value):
19 18
             if not v_re.match(regex, value):
20 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,13 +2,13 @@
2 2
 
3 3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4 4
 
5
-class EmFieldRel2Type(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6 6
 
7 7
     help = 'Relationnal field (relation2type). Take rel_to_type_id as option (an EmType uid)'
8 8
 
9 9
     def __init__(self, rel_to_type_id, **kwargs):
10 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 13
     def get_related_type(self):
14 14
         return self.model.component(self.rel_to_type_id)

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

@@ -2,10 +2,10 @@
2 2
 
3 3
 from EditorialModel.fieldtypes.generic import GenericFieldType
4 4
 
5
-class EmFieldText(GenericFieldType):
5
+class EmFieldType(GenericFieldType):
6 6
 
7 7
     help = 'A text field (big string)'
8 8
 
9 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,13 +58,10 @@ class Model(object):
58 58
 
59 59
     @staticmethod
60 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 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 63
     def name_from_emclass(em_class):
65 64
         if em_class not in Model.components_class:
66
-            if issubclass(em_class, EmField):
67
-                return 'EmField'
68 65
             return False
69 66
         return em_class.__name__
70 67
 
@@ -80,13 +77,7 @@ class Model(object):
80 77
             cls_name = kwargs['component']
81 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 82
             if cls:
92 83
                 kwargs['uid'] = uid
@@ -160,11 +151,6 @@ class Model(object):
160 151
         
161 152
         if component_type not in [ n for n in self._components.keys() if n != 'uids' ]:
162 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 154
         else:
169 155
             em_obj = self.emclass_from_name(component_type)
170 156
 

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

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

Loading…
Cancel
Save