270 self.e_schema.check_perm(self._cw, action, eid=self.eid) |
270 self.e_schema.check_perm(self._cw, action, eid=self.eid) |
271 |
271 |
272 def has_perm(self, action): |
272 def has_perm(self, action): |
273 return self.e_schema.has_perm(self._cw, action, eid=self.eid) |
273 return self.e_schema.has_perm(self._cw, action, eid=self.eid) |
274 |
274 |
275 def view(self, vid, __registry='views', **kwargs): |
275 def view(self, __vid, __registry='views', **kwargs): |
276 """shortcut to apply a view on this entity""" |
276 """shortcut to apply a view on this entity""" |
277 view = self._cw.vreg[__registry].select(vid, self._cw, rset=self.cw_rset, |
277 view = self._cw.vreg[__registry].select(vid, self._cw, rset=self.cw_rset, |
278 row=self.cw_row, col=self.cw_col, |
278 row=self.cw_row, col=self.cw_col, |
279 **kwargs) |
279 **kwargs) |
280 return view.render(row=self.cw_row, col=self.cw_col, **kwargs) |
280 return view.render(row=self.cw_row, col=self.cw_col, **kwargs) |
475 or attrschema.type == 'Password': |
475 or attrschema.type == 'Password': |
476 self[attr] = None |
476 self[attr] = None |
477 continue |
477 continue |
478 yield attr |
478 yield attr |
479 |
479 |
|
480 _cw_completed = False |
480 def complete(self, attributes=None, skip_bytes=True): |
481 def complete(self, attributes=None, skip_bytes=True): |
481 """complete this entity by adding missing attributes (i.e. query the |
482 """complete this entity by adding missing attributes (i.e. query the |
482 repository to fill the entity) |
483 repository to fill the entity) |
483 |
484 |
484 :type skip_bytes: bool |
485 :type skip_bytes: bool |
485 :param skip_bytes: |
486 :param skip_bytes: |
486 if true, attribute of type Bytes won't be considered |
487 if true, attribute of type Bytes won't be considered |
487 """ |
488 """ |
488 assert self.has_eid() |
489 assert self.has_eid() |
|
490 if self._cw_completed: |
|
491 return |
|
492 if attributes is None: |
|
493 self._cw_completed = True |
489 varmaker = rqlvar_maker() |
494 varmaker = rqlvar_maker() |
490 V = varmaker.next() |
495 V = varmaker.next() |
491 rql = ['WHERE %s eid %%(x)s' % V] |
496 rql = ['WHERE %s eid %%(x)s' % V] |
492 selected = [] |
497 selected = [] |
493 for attr in (attributes or self.to_complete_attributes(skip_bytes)): |
498 for attr in (attributes or self.to_complete_attributes(skip_bytes)): |
761 else: |
766 else: |
762 assert role |
767 assert role |
763 self._related_cache.pop('%s_%s' % (rtype, role), None) |
768 self._related_cache.pop('%s_%s' % (rtype, role), None) |
764 |
769 |
765 def clear_all_caches(self): |
770 def clear_all_caches(self): |
|
771 """flush all caches on this entity. Further attributes/relations access |
|
772 will triggers new database queries to get back values. |
|
773 |
|
774 If you use custom caches on your entity class (take care to @cached!), |
|
775 you should override this method to clear them as well. |
|
776 """ |
|
777 # clear attributes cache |
766 haseid = 'eid' in self |
778 haseid = 'eid' in self |
|
779 self._cw_completed = False |
767 self.clear() |
780 self.clear() |
768 for rschema, _, role in self.e_schema.relation_definitions(): |
|
769 self.clear_related_cache(rschema.type, role) |
|
770 # set eid if it was in, else we may get nasty error while editing this |
781 # set eid if it was in, else we may get nasty error while editing this |
771 # entity if it's bound to a repo session |
782 # entity if it's bound to a repo session |
772 if haseid: |
783 if haseid: |
773 self['eid'] = self.eid |
784 self['eid'] = self.eid |
|
785 # clear relations cache |
|
786 for rschema, _, role in self.e_schema.relation_definitions(): |
|
787 self.clear_related_cache(rschema.type, role) |
774 |
788 |
775 # raw edition utilities ################################################### |
789 # raw edition utilities ################################################### |
776 |
790 |
777 def set_attributes(self, _cw_unsafe=False, **kwargs): |
791 def set_attributes(self, _cw_unsafe=False, **kwargs): |
778 assert kwargs |
792 assert kwargs |