浏览代码

Correct the _LeObject.get() method and add some methods to LeType

Now the _LeObject.get() method should be able to return LeType child classes instance
LeType has two new methods :
	- LeTypes.datas() @property method that returns a dict(FIELDNAME:FIELDVALUE)
	- LeType.populate() that fetch from datassource missing fieldvalues
Yann Weber 9 年前
父节点
当前提交
c48147e732
共有 3 个文件被更改,包括 53 次插入1 次删除
  1. 2
    0
      leobject/leclass.py
  2. 22
    1
      leobject/leobject.py
  3. 29
    0
      leobject/letype.py

+ 2
- 0
leobject/leclass.py 查看文件

@@ -12,6 +12,8 @@ class LeClass(object):
12 12
     _linked_types = dict()
13 13
     ## @brief Stores fieldgroups and the fields they contains
14 14
     _fieldgroups = dict()
15
+    ## @brief Stores the EM uid
16
+    _class_id = None
15 17
 
16 18
     ## @brief Instanciate a new LeClass
17 19
     # @param model Model : The editorial model

+ 22
- 1
leobject/leobject.py 查看文件

@@ -23,6 +23,16 @@ class _LeObject(object):
23 23
     # @param **kwargs dict : datas usefull to instanciate a _LeObject
24 24
     def __init__(self, **kwargs):
25 25
         raise NotImplementedError("Abstract constructor")
26
+    
27
+    ## @brief Given a ME uid return the corresponding LeClass or LeType class
28
+    # @return a LeType or LeClass child class
29
+    # @throw KeyError if no corresponding child classes
30
+    def uid2leobj(cls, uid):
31
+        uid = int(uid)
32
+        if uid not in cls._me_uid:
33
+            raise KeyError("No LeType or LeClass child classes with uid '%d'"%uid)
34
+        return cls._me_uid[uid]
35
+        
26 36
 
27 37
     ## @brief update an existing LeObject
28 38
     # @param lodel_id int | (int): lodel_id of the object(s) where to apply changes
@@ -78,6 +88,8 @@ class _LeObject(object):
78 88
         #Fetching LeType
79 89
         if typename is None:
80 90
             letype = None
91
+            if 'type_id' not in field_list:
92
+                field_list.append('type_id')
81 93
         else:
82 94
             letype = leobject.lefactory.LeFactory.leobj_from_name(typename)
83 95
 
@@ -105,8 +117,17 @@ class _LeObject(object):
105 117
         filters = [f for f in filters if not self._field_is_relational(f[0])]
106 118
         #Checking the rest of the fields
107 119
         LeFactory._check_fields(letype, leclass, [ f[0] for f in filters ])
120
+        
121
+        #Fetching datas from datasource
122
+        datas = self._datasource.get(emclass, emtype, field_list, filters, relational_filters)
123
+        
124
+        #Instanciating corresponding LeType child classes with datas
125
+        result = list()
126
+        for leobj_datas in datas:
127
+            letype = self.uid2leobj(datas['type_id']) if letype is None else letype
128
+            result.append(letype(datas))
108 129
 
109
-        return self._datasource.get(emclass, emtype, filters, relational_filters)
130
+        return result
110 131
 
111 132
     ## @brief Check if a fieldname is valid
112 133
     # @param letype LeType|None : The concerned type (or None)

+ 29
- 0
leobject/letype.py 查看文件

@@ -14,6 +14,8 @@ class LeType(object):
14 14
     _superiors = list()
15 15
     ## @brief Stores the class of LeClass
16 16
     _leclass = None
17
+    ## @brief Stores the EM uid
18
+    _type_id = None
17 19
     
18 20
     ## @brief Instanciate a new LeType
19 21
     # @param lodel_id : The lodel id
@@ -23,11 +25,37 @@ class LeType(object):
23 25
             raise NotImplementedError("Abstract class")
24 26
 
25 27
         self.lodel_id = lodel_id
28
+
29
+        if 'type_id' in kwargs:
30
+            if self.__class__._type_id != int(kwargs['type_id']):
31
+                raise RuntimeError("Trying to instanciate a %s with an EM uid that is not correct"%self.__class__.__name__)
32
+
26 33
         ## Populate the object from the datas received in kwargs
27 34
         for name, value in kwargs.items():
28 35
             if name not in self._fields:
29 36
                 raise AttributeError("No such field '%s' for %s"%(name, self.__class__.__name__))
30 37
             setattr(self, name, value)
38
+    
39
+    ## @brief Populate the LeType wih datas from DB
40
+    # @param field_list None|list : List of fieldname to fetch. If None fetch all the missing datas
41
+    def populate(self, field_list=None):
42
+        if field_list == None:
43
+            field_list = [ fname for fname in self._fields if not hasattr(self, fname) ]
44
+
45
+        fdatas = self._datasource.get(self._leclass, self.__class__, 'lodel_id = %d'%self.lodel_id)
46
+        for fname, fdats in fdatas[0].items():
47
+            setattr(self, name, value)
48
+
49
+    ## @brief Get a fieldname:value dict
50
+    # @warning Giving True as full argument can represent a performances issue
51
+    # @param full bool : If true populate the object before returning the datas
52
+    # @return A dict with field name as key and the field value as value
53
+    @property
54
+    def datas(self, full=False):
55
+        if full:
56
+            self.populate()
57
+        return { fname: getattr(self, fname) for fname in self._fields if hasattr(self,fname) }
58
+            
31 59
 
32 60
     ## @brief Delete the LeType from Db
33 61
     # @note equivalent to LeType::delete(this.lodel_id)
@@ -63,6 +91,7 @@ class LeType(object):
63 91
     # @throw InvalidArgumentError if invalid argument
64 92
     @classmethod
65 93
     def insert(self, **datas):
94
+        self.check_datas_or_raise(datas, complete=True)
66 95
         super(LeType, self).insert(typename=self.__class__.__name__, classname=self._leclass.__name__, **datas)
67 96
         pass
68 97
     

正在加载...
取消
保存