# HG changeset patch # User Aurelien Campeas # Date 1373542347 -7200 # Node ID 723e2c586ea36738bb01f3c4ff62d3bc54b8e448 # Parent 4b3e657d17ab4645c25c823eac4e4ab3f9fca221 [entity] Entity.related(): add a targettypes argument (closes #2957313) This allows to restrict the entity types returned by the method (passed to cw_related_rql). When such an argument is given, no caching happens. diff -r 4b3e657d17ab -r 723e2c586ea3 entity.py --- a/entity.py Wed Aug 28 12:14:20 2013 +0200 +++ b/entity.py Thu Jul 11 13:32:27 2013 +0200 @@ -969,7 +969,7 @@ return value def related(self, rtype, role='subject', limit=None, entities=False, # XXX .cw_related - safe=False): + safe=False, targettypes=None): """returns a resultset of related entities :param rtype: @@ -983,10 +983,13 @@ :param safe: if True, an empty rset/list of entities will be returned in case of :exc:`Unauthorized`, else (the default), the exception is propagated + :param targettypes: + a tuple of target entity types to restrict the query """ rtype = str(rtype) - if limit is None: - # we cannot do much wrt cache on limited queries + # Caching restricted/limited results is best avoided. + cacheable = limit is None and targettypes is None + if cacheable: cache_key = '%s_%s' % (rtype, role) if cache_key in self._cw_related_cache: return self._cw_related_cache[cache_key][entities] @@ -994,7 +997,7 @@ if entities: return [] return self._cw.empty_rset() - rql = self.cw_related_rql(rtype, role, limit=limit) + rql = self.cw_related_rql(rtype, role, limit=limit, targettypes=targettypes) try: rset = self._cw.execute(rql, {'x': self.eid}) except Unauthorized: @@ -1002,9 +1005,9 @@ raise rset = self._cw.empty_rset() if entities: - if limit is None: + if cacheable: self.cw_set_relation_cache(rtype, role, rset) - return self.related(rtype, role, limit, entities) + return self.related(rtype, role, entities=entities) return list(rset.entities()) else: return rset diff -r 4b3e657d17ab -r 723e2c586ea3 test/data/schema.py --- a/test/data/schema.py Wed Aug 28 12:14:20 2013 +0200 +++ b/test/data/schema.py Thu Jul 11 13:32:27 2013 +0200 @@ -41,7 +41,7 @@ constraints=[RQLConstraint('NOT EXISTS(O contrat_exclusif S)')]) dirige = SubjectRelation('Societe', cardinality='??', constraints=[RQLConstraint('S actionnaire O')]) - associe = SubjectRelation('Personne', cardinality='1*', + associe = SubjectRelation('Personne', cardinality='?*', constraints=[RQLConstraint('S actionnaire SOC, O actionnaire SOC')]) class Ami(EntityType): diff -r 4b3e657d17ab -r 723e2c586ea3 test/unittest_entity.py --- a/test/unittest_entity.py Wed Aug 28 12:14:20 2013 +0200 +++ b/test/unittest_entity.py Thu Jul 11 13:32:27 2013 +0200 @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# copyright 2003-2012 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -132,6 +132,12 @@ self.assertEqual(sorted(user._cw_related_cache), ['in_group_subject', 'primary_email_subject']) for group in groups: self.assertFalse('in_group_subject' in group._cw_related_cache, list(group._cw_related_cache)) + user.cw_clear_all_caches() + user.related('in_group', entities=True) + self.assertIn('in_group_subject', user._cw_related_cache) + user.cw_clear_all_caches() + user.related('in_group', targettypes=('CWGroup',), entities=True) + self.assertNotIn('in_group_subject', user._cw_related_cache) def test_related_limit(self): req = self.request() @@ -145,6 +151,18 @@ self.assertEqual(len(p.related('tags', 'object', entities=True, limit=2)), 2) self.assertEqual(len(p.related('tags', 'object', entities=True)), 4) + def test_related_targettypes(self): + req = self.request() + p = req.create_entity('Personne', nom=u'Loxodonta', prenom=u'Babar') + n = req.create_entity('Note', type=u'scratch', ecrit_par=p) + t = req.create_entity('Tag', name=u'a tag', tags=(p, n)) + self.commit() + req = self.request() + t = req.entity_from_eid(t.eid) + self.assertEqual(2, t.related('tags').rowcount) + self.assertEqual(1, t.related('tags', targettypes=('Personne',)).rowcount) + self.assertEqual(1, t.related('tags', targettypes=('Note',)).rowcount) + def test_cw_instantiate_relation(self): req = self.request() p1 = req.create_entity('Personne', nom=u'di')