# HG changeset patch # User Sylvain Thénault # Date 1479489314 -3600 # Node ID b2ceb483e056dc87c90f2b54900fdb815c6ad83b # Parent a166ddb503aa8184ff9dcdf6748de132fef87f93 [views/optimization] Makes has_editable_relations predicate less costly by using generator The `has_editable_relations` predicate is used to say if the 'modify' action should appear. To do so, it checks if anything is editable (ie. something in the attributes, relations or inlined section of the automatic form). This may be costly since it may have to check several permissions. To optimize this a bit, this cset turns list into generator so that we'll avoid unnecessary work as soon as we find a match. diff -r a166ddb503aa -r b2ceb483e056 cubicweb/web/views/actions.py --- a/cubicweb/web/views/actions.py Thu Nov 17 11:03:19 2016 +0100 +++ b/cubicweb/web/views/actions.py Fri Nov 18 18:15:14 2016 +0100 @@ -48,7 +48,7 @@ # display action anyway form = entity._cw.vreg['forms'].select('edition', entity._cw, entity=entity, mainform=False) - for dummy in form.editable_relations(): + for dummy in form.iter_editable_relations(): return 1 for dummy in form.inlined_form_views(): return 1 diff -r a166ddb503aa -r b2ceb483e056 cubicweb/web/views/autoform.py --- a/cubicweb/web/views/autoform.py Thu Nov 17 11:03:19 2016 +0100 +++ b/cubicweb/web/views/autoform.py Fri Nov 18 18:15:14 2016 +0100 @@ -861,24 +861,25 @@ """return a list of (relation schema, role) to edit for the entity""" if self.display_fields is not None: schema = self._cw.vreg.schema - return [(schema[rtype], role) for rtype, role in self.display_fields] + for rtype, role in self.display_fields: + yield (schema[rtype], role) if self.edited_entity.has_eid() and not self.edited_entity.cw_has_perm('update'): - return [] + return action = 'update' if self.edited_entity.has_eid() else 'add' - return [(rtype, role) for rtype, _, role in self._relations_by_section( - 'attributes', action, strict)] + for rtype, _, role in self._relations_by_section('attributes', action, strict): + yield (rtype, role) def editable_relations(self): """return a sorted list of (relation's label, relation'schema, role) for relations in the 'relations' section """ - result = [] - for rschema, _, role in self._relations_by_section('relations', - strict=True): - result.append( (rschema.display_name(self.edited_entity._cw, role, - self.edited_entity.cw_etype), - rschema, role) ) - return sorted(result) + return sorted(self.iter_editable_relations()) + + def iter_editable_relations(self): + for rschema, _, role in self._relations_by_section('relations', strict=True): + yield (rschema.display_name(self.edited_entity._cw, role, + self.edited_entity.cw_etype), + rschema, role) def inlined_relations(self): """return a list of (relation schema, target schemas, role) matching @@ -889,10 +890,8 @@ # inlined forms control #################################################### def inlined_form_views(self): - """compute and return list of inlined form views (hosting the inlined - form object) + """Yield inlined form views (hosting the inlined form object) """ - allformviews = [] entity = self.edited_entity for rschema, ttypes, role in self.inlined_relations(): # show inline forms only if there's one possible target type @@ -904,11 +903,15 @@ continue tschema = ttypes[0] ttype = tschema.type - formviews = list(self.inline_edition_form_view(rschema, ttype, role)) + existing = bool(entity.related(rschema, role)) if entity.has_eid() else False + for formview in self.inline_edition_form_view(rschema, ttype, role): + yield formview + existing = True card = rschema.role_rdef(entity.e_schema, ttype, role).role_cardinality(role) - existing = entity.related(rschema, role) if entity.has_eid() else formviews if self.should_display_inline_creation_form(rschema, existing, card): - formviews += self.inline_creation_form_view(rschema, ttype, role) + for formview in self.inline_creation_form_view(rschema, ttype, role): + yield formview + existing = True # we can create more than one related entity, we thus display a link # to add new related entities if self.must_display_add_new_relation_link(rschema, role, tschema, @@ -918,9 +921,7 @@ etype=ttype, rtype=rschema, role=role, card=card, peid=self.edited_entity.eid, petype=self.edited_entity.e_schema, pform=self) - formviews.append(addnewlink) - allformviews += formviews - return allformviews + yield addnewlink def should_display_inline_creation_form(self, rschema, existing, card): """return true if a creation form should be inlined