58 |
58 |
59 :type skip_copy_for: list |
59 :type skip_copy_for: list |
60 :cvar skip_copy_for: a list of relations that should be skipped when copying |
60 :cvar skip_copy_for: a list of relations that should be skipped when copying |
61 this kind of entity. Note that some relations such |
61 this kind of entity. Note that some relations such |
62 as composite relations or relations that have '?1' as object |
62 as composite relations or relations that have '?1' as object |
63 cardinality are always skipped. |
63 cardinality are always skipped. |
64 """ |
64 """ |
65 __registry__ = 'etypes' |
65 __registry__ = 'etypes' |
66 __select__ = yes() |
66 __select__ = yes() |
67 |
67 |
68 # class attributes that must be set in class definition |
68 # class attributes that must be set in class definition |
223 return id(self) |
223 return id(self) |
224 |
224 |
225 def __cmp__(self, other): |
225 def __cmp__(self, other): |
226 raise NotImplementedError('comparison not implemented for %s' % self.__class__) |
226 raise NotImplementedError('comparison not implemented for %s' % self.__class__) |
227 |
227 |
|
228 def __setitem__(self, attr, value): |
|
229 """override __setitem__ to update self.edited_attributes. |
|
230 |
|
231 Typically, a before_update_hook could do:: |
|
232 |
|
233 entity['generated_attr'] = generated_value |
|
234 |
|
235 and this way, edited_attributes will be updated accordingly |
|
236 """ |
|
237 if attr == 'eid': |
|
238 warn('[3.7] entity["eid"] = value is deprecated, use entity.eid = value instead', |
|
239 DeprecationWarning, stacklevel=2) |
|
240 self.eid = value |
|
241 else: |
|
242 super(Entity, self).__setitem__(attr, value) |
|
243 if hasattr(self, 'edited_attributes'): |
|
244 self.edited_attributes.add(attr) |
|
245 |
|
246 def __getitem__(self, key): |
|
247 if key == 'eid': |
|
248 warn('[3.7] entity["eid"] is deprecated, use entity.eid instead', |
|
249 DeprecationWarning, stacklevel=2) |
|
250 return self.eid |
|
251 return super(Entity, self).__getitem__(key) |
|
252 |
|
253 def setdefault(self, key, default): |
|
254 """override setdefault to update self.edited_attributes""" |
|
255 super(Entity, self).setdefault(key, default) |
|
256 if hasattr(self, 'edited_attributes'): |
|
257 self.edited_attributes.add(key) |
|
258 |
228 def pre_add_hook(self): |
259 def pre_add_hook(self): |
229 """hook called by the repository before doing anything to add the entity |
260 """hook called by the repository before doing anything to add the entity |
230 (before_add entity hooks have not been called yet). This give the |
261 (before_add entity hooks have not been called yet). This give the |
231 occasion to do weird stuff such as autocast (File -> Image for instance). |
262 occasion to do weird stuff such as autocast (File -> Image for instance). |
232 |
263 |
233 This method must return the actual entity to be added. |
264 This method must return the actual entity to be added. |
234 """ |
265 """ |
235 return self |
266 return self |
236 |
267 |
237 def set_eid(self, eid): |
268 def set_eid(self, eid): |
238 self.eid = self['eid'] = eid |
269 self.eid = eid |
239 |
270 |
240 def has_eid(self): |
271 def has_eid(self): |
241 """return True if the entity has an attributed eid (False |
272 """return True if the entity has an attributed eid (False |
242 meaning that the entity has to be created |
273 meaning that the entity has to be created |
243 """ |
274 """ |
779 """ |
810 """ |
780 # clear attributes cache |
811 # clear attributes cache |
781 haseid = 'eid' in self |
812 haseid = 'eid' in self |
782 self._cw_completed = False |
813 self._cw_completed = False |
783 self.clear() |
814 self.clear() |
784 # set eid if it was in, else we may get nasty error while editing this |
|
785 # entity if it's bound to a repo session |
|
786 if haseid: |
|
787 self['eid'] = self.eid |
|
788 # clear relations cache |
815 # clear relations cache |
789 for rschema, _, role in self.e_schema.relation_definitions(): |
816 for rschema, _, role in self.e_schema.relation_definitions(): |
790 self.clear_related_cache(rschema.type, role) |
817 self.clear_related_cache(rschema.type, role) |
791 # rest path unique cache |
818 # rest path unique cache |
792 try: |
819 try: |
856 # in the dictionary |
883 # in the dictionary |
857 if self._cw is None: |
884 if self._cw is None: |
858 _ = unicode |
885 _ = unicode |
859 else: |
886 else: |
860 _ = self._cw._ |
887 _ = self._cw._ |
861 self.e_schema.check(self, creation=creation, _=_) |
888 if creation or not hasattr(self, 'edited_attributes'): |
|
889 # on creations, we want to check all relations, especially |
|
890 # required attributes |
|
891 relations = None |
|
892 else: |
|
893 relations = [self._cw.vreg.schema.rschema(rtype) |
|
894 for rtype in self.edited_attributes] |
|
895 self.e_schema.check(self, creation=creation, _=_, |
|
896 relations=relations) |
862 |
897 |
863 def fti_containers(self, _done=None): |
898 def fti_containers(self, _done=None): |
864 if _done is None: |
899 if _done is None: |
865 _done = set() |
900 _done = set() |
866 _done.add(self.eid) |
901 _done.add(self.eid) |
930 return self |
965 return self |
931 return eobj.get_value(self._attrname) |
966 return eobj.get_value(self._attrname) |
932 |
967 |
933 def __set__(self, eobj, value): |
968 def __set__(self, eobj, value): |
934 eobj[self._attrname] = value |
969 eobj[self._attrname] = value |
935 if hasattr(eobj, 'edited_attributes'): |
|
936 eobj.edited_attributes.add(self._attrname) |
|
937 |
970 |
938 class Relation(object): |
971 class Relation(object): |
939 """descriptor that controls schema relation access""" |
972 """descriptor that controls schema relation access""" |
940 _role = None # for pylint |
973 _role = None # for pylint |
941 |
974 |