def test_provides_resource(self): coll = create_collection() mb = next(iter(coll)) self.assert_true(provides_member_resource(type(mb))) self.assert_true(provides_member_resource(mb)) self.assert_false(provides_member_resource(coll)) self.assert_true(provides_resource(type(mb))) self.assert_true(provides_resource(mb)) self.assert_true(provides_collection_resource(type(coll))) self.assert_true(provides_collection_resource(coll)) self.assert_false(provides_collection_resource(mb)) self.assert_true(provides_resource(type(coll))) self.assert_true(provides_resource(coll)) self.assert_false(provides_resource(mb.get_entity()))
def test_provides_resource(self): coll = create_collection() mb = iter(coll).next() self.assert_true(provides_member_resource(type(mb))) self.assert_true(provides_member_resource(mb)) self.assert_false(provides_member_resource(coll)) self.assert_true(provides_resource(type(mb))) self.assert_true(provides_resource(mb)) self.assert_true(provides_collection_resource(type(coll))) self.assert_true(provides_collection_resource(coll)) self.assert_false(provides_collection_resource(mb)) self.assert_true(provides_resource(type(coll))) self.assert_true(provides_resource(coll)) self.assert_false(provides_resource(mb.get_entity()))
def run(self): csv_rdr = CsvDictReader(self._stream, dialect=self.get_option('dialect')) is_member_rpr = provides_member_resource(self._resource_class) if is_member_rpr: coll_data_el = None else: coll_data_el = self._mapping.create_data_element() for row_data in csv_rdr: if self.__is_first_row: self.__first_row_field_names = set(csv_rdr.fieldnames) self.__first_row_data = row_data.copy() if not self.__coll_data is None: # We need to generate the row data key now because we # get attribute values destructively from the row_data. self.__row_data_key = self.__coll_data.make_key(row_data) mb_data_el = self.__process_row(row_data, self._resource_class, MappedAttributeKey(())) if self.__is_first_row: self.__is_first_row = False if len(self.__first_row_field_names) > 0: raise ValueError('Invalid field name(s): %s' % ','.join(self.__first_row_field_names)) if None in row_data.keys(): raise ValueError('Invalid row length.') if not coll_data_el is None: # The member data element will be None for all but the first # member of nested collection resources. if not mb_data_el is None: coll_data_el.add_member(mb_data_el) if is_member_rpr: result_data_el = mb_data_el else: result_data_el = coll_data_el return result_data_el
def create_from_resource(cls, resource): # Create the wrapping element. mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(type(resource)) xml_ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) options = {XML_NAMESPACE_OPTION:xml_ns} rc_data_el = mp.create_data_element_from_resource(resource) if provides_member_resource(resource): link_el = cls.create(resource_to_url(resource), RESOURCE_KINDS.MEMBER, id=str(resource.id), relation=resource.relation, title=resource.title, **options) rc_data_el.set('id', str(resource.id)) rc_data_el.append(link_el) else: # collection resource. # Collection links only get an actual link element if they # contain any members. link_el = cls.create(resource_to_url(resource), RESOURCE_KINDS.COLLECTION, relation=resource.relation, title=resource.title, **options) rc_data_el.append(link_el) return rc_data_el
def run(self): csv_rdr = CsvDictReader(self._stream, dialect=self.get_option('dialect')) is_member_rpr = provides_member_resource(self._resource_class) if is_member_rpr: coll_data_el = None else: coll_data_el = self._mapping.create_data_element() for row_data in csv_rdr: if self.__is_first_row: self.__first_row_field_names = set(csv_rdr.fieldnames) self.__first_row_data = row_data.copy() if not self.__coll_data is None: # We need to generate the row data key now because we # get attribute values destructively from the row_data. self.__row_data_key = self.__coll_data.make_key(row_data) mb_data_el = self.__process_row(row_data, self._resource_class, MappedAttributeKey(())) if self.__is_first_row: self.__is_first_row = False if len(self.__first_row_field_names) > 0: raise ValueError('Invalid field name(s): %s' % ','.join(self.__first_row_field_names)) if None in row_data.keys(): raise ValueError('Invalid row length.') if not coll_data_el is None: # The member data element will be None for all but the first # member of nested collection resources. if not mb_data_el is None: coll_data_el.add_member(mb_data_el) if is_member_rpr: result_data_el = mb_data_el else: result_data_el = coll_data_el return result_data_el
def create_from_resource(cls, resource): # Create the wrapping element. mp_reg = get_mapping_registry(XmlMime) mp = mp_reg.find_or_create_mapping(type(resource)) xml_ns = mp.configuration.get_option(XML_NAMESPACE_OPTION) options = {XML_NAMESPACE_OPTION:xml_ns} rc_data_el = mp.create_data_element_from_resource(resource) if provides_member_resource(resource): link_el = cls.create(resource_to_url(resource), RESOURCE_KINDS.MEMBER, id=str(resource.id), relation=resource.relation, title=resource.title, **options) rc_data_el.set('id', str(resource.id)) rc_data_el.append(link_el) else: # collection resource. # Collection links only get an actual link element if they # contain any members. link_el = cls.create(resource_to_url(resource), RESOURCE_KINDS.COLLECTION, relation=resource.relation, title=resource.title, **options) rc_data_el.append(link_el) return rc_data_el
def _process_request_data(self, data): if not provides_resource(data): rpr = self._get_request_representer() resource = rpr.resource_from_data(data) else: resource = data member_was_posted = provides_member_resource(resource) if member_was_posted: new_members = [resource] else: new_members = resource was_created = True for new_member in new_members: if self.context.get(new_member.__name__) is not None: # We have a member with the same name - 409 Conflict. response = self._handle_conflict(new_member.__name__) was_created = False break else: self.context.add(new_member) if was_created: if member_was_posted: new_location = resource_to_url(resource, request=self.request) else: new_location = resource_to_url(self.context, request=self.request) self.request.response.status = self._status(HTTPCreated) self.request.response.headerlist = [('Location', new_location)] response = self._get_result(resource) return response
def create_from_resource(cls, resource): if provides_member_resource(resource): kind = ResourceKinds.MEMBER elif provides_collection_resource(resource): kind = ResourceKinds.COLLECTION else: raise ValueError('"%s" is not a resource.' % resource) return cls.create(resource_to_url(resource), kind, relation=resource.relation, title=resource.title)
def create_from_resource(cls, resource): if provides_member_resource(resource): kind = RESOURCE_KINDS.MEMBER opts = dict(id=resource.id) elif provides_collection_resource(resource): kind = RESOURCE_KINDS.COLLECTION opts = {} else: raise ValueError('"%s" is not a resource.' % resource) return cls.create(resource_to_url(resource), kind, relation=resource.relation, title=resource.title, **opts)
def build_resource_graph(resource, dependency_graph=None): """ Traverses the graph of resources that is reachable from the given resource. If a resource dependency graph is given, links to other resources are only followed if the dependency graph has an edge connecting the two corresponding resource classes; otherwise, a default graph is built which ignores all direct cyclic resource references. :resource: a :class:`everest.resources.MemberResource` instance. :returns: a :class:`ResourceGraph` instance representing the graph of resources reachable from the given resource. """ def visit(rc, grph, dep_grph): mb_cls = type(rc) attr_map = get_resource_class_attributes(mb_cls) for attr_name, attr in iteritems_(attr_map): if is_resource_class_terminal_attribute(mb_cls, attr_name): continue # Only follow the resource attribute if the dependency graph # has an edge here. child_mb_cls = get_member_class(attr.attr_type) if not dep_grph.has_edge((mb_cls, child_mb_cls)): continue child_rc = getattr(rc, attr_name) if is_resource_class_collection_attribute(mb_cls, attr_name): for child_mb in child_rc: if not grph.has_node( child_mb): # Ignore cyclic references. grph.add_node(child_mb) grph.add_edge((rc, child_mb)) visit(child_mb, grph, dep_grph) else: # Member. if not grph.has_node(child_rc): # Ignore cyclic references. grph.add_node(child_rc) grph.add_edge((rc, child_rc)) visit(child_rc, grph, dep_grph) if dependency_graph is None: dependency_graph = build_resource_dependency_graph( [get_member_class(resource)]) graph = ResourceGraph() if provides_member_resource(resource): rcs = [resource] else: rcs = resource for rc in rcs: graph.add_node(rc) visit(rc, graph, dependency_graph) return graph
def create_from_resource(cls, resource): if provides_member_resource(resource): kind = RESOURCE_KINDS.MEMBER opts = dict(id=resource.id) elif provides_collection_resource(resource): kind = RESOURCE_KINDS.COLLECTION opts = {} else: raise ValueError('"%s" is not a resource.' % resource) return cls.create(resource_to_url(resource), kind, relation=resource.relation, title=resource.title, **opts)
def map_to_data_element(self, resource): # We use the XML mapping for the content serialization. xml_mp_reg = get_mapping_registry(XmlMime) xml_mp = xml_mp_reg.find_or_create_mapping(type(resource)) ns_map = self.mapping_registry.namespace_map atom_mp = self.mapping_registry.find_or_create_mapping(type(resource)) data_el = \ atom_mp.data_element_class.create_from_resource(resource, ns_map=ns_map) if provides_member_resource(resource): self.__map_member_to_data_element(data_el, resource, xml_mp) else: self.__map_collection_to_data_element(data_el, resource, xml_mp) return data_el
def map_to_data_element(self, resource): # We use the XML mapping for the content serialization. xml_mp_reg = get_mapping_registry(XmlMime) xml_mp = xml_mp_reg.find_or_create_mapping(type(resource)) ns_map = self.mapping_registry.namespace_map atom_mp = self.mapping_registry.find_or_create_mapping(type(resource)) data_el = \ atom_mp.data_element_class.create_from_resource(resource, ns_map=ns_map) if provides_member_resource(resource): self.__map_member_to_data_element(data_el, resource, xml_mp) else: self.__map_collection_to_data_element(data_el, resource, xml_mp) return data_el
def build_resource_graph(resource, dependency_graph=None): """ Traverses the graph of resources that is reachable from the given resource. If a resource dependency graph is given, links to other resources are only followed if the dependency graph has an edge connecting the two corresponding resource classes; otherwise, a default graph is built which ignores all direct cyclic resource references. :resource: a :class:`everest.resources.MemberResource` instance. :returns: a :class:`ResourceGraph` instance representing the graph of resources reachable from the given resource. """ def visit(rc, grph, dep_grph): mb_cls = type(rc) attr_map = mb_cls.get_attributes() for attr_name, attr in attr_map.iteritems(): if mb_cls.is_terminal(attr_name): continue # Only follow the resource attribute if the dependency graph # has an edge here. child_mb_cls = get_member_class(attr.value_type) if not dep_grph.has_edge((mb_cls, child_mb_cls)): continue child_rc = getattr(rc, attr_name) if mb_cls.is_collection(attr_name): for child_mb in child_rc: if not grph.has_node(child_mb): # Ignore cyclic references. grph.add_node(child_mb) grph.add_edge((rc, child_mb)) visit(child_mb, grph, dep_grph) else: # Member. if not grph.has_node(child_rc): # Ignore cyclic references. grph.add_node(child_rc) grph.add_edge((rc, child_rc)) visit(child_rc, grph, dep_grph) if dependency_graph is None: dependency_graph = build_resource_dependency_graph( [get_member_class(resource)]) graph = ResourceGraph() if provides_member_resource(resource): rcs = [resource] else: rcs = resource for rc in rcs: graph.add_node(rc) visit(rc, graph, dependency_graph) return graph
def loader_options(self): """ Dictionary mapping each entity class to configure a loader for to a list of (possibly nested) entity attribute names. """ all_keys = set(self.__attr_map.keys()) # Go through the collected keys and through out all keys which are # subkeys of others to eliminate redundancy. for key in sorted(self.__attr_map): for idx in range(1, len(key)): sub_key = key[:-idx] if sub_key in all_keys: all_keys.remove(sub_key) if provides_member_resource(self._context): # If the context is a member, we need to configure the loaders # for the entity class belonging to each of its resource # attributes. Only nested keys collected from the representer # configuration need to be configured (and the corresponding # nested entity attribute needs to be shortened). loader_option_map = defaultdict(list) for key in all_keys: entity_attr_names = self.__attr_map[key] if len(entity_attr_names) > 1: ent_attr_name = entity_attr_names[0] nested_attr_name = '.'.join(entity_attr_names[1:]) opts = loader_option_map[ent_attr_name] opts.append(nested_attr_name) # Translate to entity classes as keys. This is tricky as the # keys in the loader option map can itself be nested attributes. for ent_attr_name, nested_attr_names in loader_option_map.items(): ent_attr_name_tokens = ent_attr_name.split('.') ent_cls = get_entity_class(self._context) ent_cls_attr = getattr(ent_cls, ent_attr_name_tokens[0]) ent_cls = ent_cls_attr.property.mapper.entity if len(ent_attr_name_tokens) > 1: prefix = '.'.join(ent_attr_name_tokens[1:]) loader_option_map[ent_cls] = \ ["%s.%s" % (prefix, token) for token in nested_attr_names] else: loader_option_map[ent_cls] = nested_attr_names del loader_option_map[ent_attr_name] else: # If the context is a collection, we need to configure the # loader for its entity class. loader_option_map = {get_entity_class(self._context) : ['.'.join(self.__attr_map[key]) for key in all_keys]} return loader_option_map
def __collect_mapped_attributes(self, mapped_class, key): if isinstance(key, MappedAttributeKey): names = key.names else: names = key collected_mp_attrs = OrderedDict() is_mapped_cls = mapped_class is self.__mapped_cls if len(names) == 0 and is_mapped_cls: # Bootstrapping: fetch resource attributes and create new # mapped attributes. rc_attrs = get_resource_class_attributes(self.__mapped_cls) for rc_attr in itervalues_(rc_attrs): attr_key = names + (rc_attr.resource_attr,) attr_mp_opts = \ self.__configurations[-1].get_attribute_options(attr_key) new_mp_attr = MappedAttribute(rc_attr, options=attr_mp_opts) collected_mp_attrs[new_mp_attr.resource_attr] = new_mp_attr else: # Indirect access - fetch mapped attributes from some other # class' mapping and clone. if is_mapped_cls: mp = self elif len(names) == 0 and self.__is_collection_mapping: if provides_member_resource(mapped_class): # Mapping a polymorphic member class. mapped_coll_cls = get_collection_class(mapped_class) else: # Mapping a derived collection class. mapped_coll_cls = mapped_class mp = self.__mp_reg.find_or_create_mapping(mapped_coll_cls) else: mp = self.__mp_reg.find_or_create_mapping(mapped_class) mp_attrs = mp.get_attribute_map() for mp_attr in itervalues_(mp_attrs): attr_key = names + (mp_attr.name,) attr_mp_opts = \ dict(((k, v) for (k, v) in iteritems_(self.__configurations[-1] .get_attribute_options(attr_key)) if not v is None)) clnd_mp_attr = mp_attr.clone(options=attr_mp_opts) collected_mp_attrs[mp_attr.name] = clnd_mp_attr return collected_mp_attrs
def __collect_mapped_attributes(self, mapped_class, key): if isinstance(key, MappedAttributeKey): names = key.names else: names = key collected_mp_attrs = OrderedDict() is_mapped_cls = mapped_class is self.__mapped_cls if len(names) == 0 and is_mapped_cls: # Bootstrapping: fetch resource attributes and create new # mapped attributes. rc_attrs = get_resource_class_attributes(self.__mapped_cls) for rc_attr in itervalues_(rc_attrs): attr_key = names + (rc_attr.resource_attr,) attr_mp_opts = \ self.__configurations[-1].get_attribute_options(attr_key) new_mp_attr = MappedAttribute(rc_attr, options=attr_mp_opts) collected_mp_attrs[new_mp_attr.resource_attr] = new_mp_attr else: # Indirect access - fetch mapped attributes from some other # class' mapping and clone. if is_mapped_cls: mp = self elif len(names) == 0 and self.__is_collection_mapping: if provides_member_resource(mapped_class): # Mapping a polymorphic member class. mapped_coll_cls = get_collection_class(mapped_class) else: # Mapping a derived collection class. mapped_coll_cls = mapped_class mp = self.__mp_reg.find_or_create_mapping(mapped_coll_cls) else: mp = self.__mp_reg.find_or_create_mapping(mapped_class) mp_attrs = mp.get_attribute_map() for mp_attr in itervalues_(mp_attrs): attr_key = names + (mp_attr.name,) attr_mp_opts = \ dict(((k, v) for (k, v) in iteritems_(self.__configurations[-1] .get_attribute_options(attr_key)) if not v is None)) clnd_mp_attr = mp_attr.clone(options=attr_mp_opts) collected_mp_attrs[mp_attr.resource_attr] = clnd_mp_attr return collected_mp_attrs
def _process_request_data(self, data): if not provides_resource(data): rpr = self._get_request_representer() resource = rpr.resource_from_data(data) else: resource = data data_is_member = provides_member_resource(resource) if data_is_member: new_members = [resource] else: new_members = resource was_created = True sync_with_repo = False for new_member in new_members: name_is_none = new_member.__name__ is None sync_with_repo |= name_is_none if not name_is_none \ and not self.context.get(new_member.__name__) is None: # We have a member with the same name - 409 Conflict. result = self._handle_conflict(new_member.__name__) was_created = False break else: self.context.add(new_member) if was_created: if sync_with_repo: # This is not pretty, but necessary: When the resource # name depends on the entity ID, the pending entity needs # to be flushed to the repository before we can access # the ID. self.context.get_aggregate().sync_with_repository() self.request.response.status = self._status(HTTPCreated) if data_is_member: loc_rc = resource else: loc_rc = self.context self._update_response_location_header(loc_rc) result = self._get_result(resource) return result
def _process_request_data(self, data): if not provides_resource(data): rpr = self._get_request_representer() resource = rpr.resource_from_data(data) else: resource = data data_is_member = provides_member_resource(resource) if data_is_member: new_members = [resource] else: new_members = resource was_created = True sync_with_repo = False for new_member in new_members: name_is_none = new_member.__name__ is None sync_with_repo |= name_is_none if not name_is_none \ and not self.context.get(new_member.__name__) is None: # We have a member with the same name - 409 Conflict. result = self._handle_conflict(new_member.__name__) was_created = False break else: self.context.add(new_member) if was_created: if sync_with_repo: # This is not pretty, but necessary: When the resource # name depends on the entity ID, the pending entity needs # to be flushed to the repository before we can access # the ID. self.context.get_aggregate().sync_with_repository() self.request.response.status = self._status(HTTPCreated) if data_is_member: loc_rc = resource else: loc_rc = self.context self._update_response_location_header(loc_rc) result = self._get_result(resource) return result
def _process_request_data(self, data): if not provides_resource(data): rpr = self._get_request_representer() resource = rpr.resource_from_data(data) else: resource = data member_was_posted = provides_member_resource(resource) if member_was_posted: new_members = [resource] else: new_members = resource was_created = True parent_collection_is_nested = self.context.is_nested for new_member in new_members: if parent_collection_is_nested: # If we are POSTing to a nested collection, the framework # tries to infer the parent for each member if it has not # been provided by the representation. self.__check_parent(new_member) if self.context.get(new_member.__name__) is not None: # We have a member with the same name - 409 Conflict. response = self._handle_conflict(new_member.__name__) was_created = False break else: self.context.add(new_member) if was_created: if member_was_posted: new_location = resource_to_url(resource, request=self.request) else: new_location = resource_to_url(self.context, request=self.request) self.request.response.status = self._status(HTTPCreated) self.request.response.headerlist = [('Location', new_location)] response = self._get_result(resource) return response
def _process_request_data(self, data): if not provides_resource(data): rpr = self._get_request_representer() resource = rpr.resource_from_data(data) else: resource = data member_was_posted = provides_member_resource(resource) if member_was_posted: new_members = [resource] else: new_members = resource was_created = True parent_collection_is_nested = self.context.is_nested for new_member in new_members: if parent_collection_is_nested: # If we are POSTing to a nested collection, the framework # tries to infer the parent for each member if it has not # been provided by the representation. self.__check_parent(new_member) if self.context.get(new_member.__name__) is not None: # We have a member with the same name - 409 Conflict. response = self._handle_conflict(new_member.__name__) was_created = False break else: self.context.add(new_member) if was_created: if member_was_posted: new_location = resource_to_url(resource, request=self.request) else: new_location = resource_to_url(self.context, request=self.request) self.request.response.status = self._status(HTTPCreated) self.request.response.headerlist = [('Location', new_location)] response = self._get_result(resource) return response
def __add_resource_view(self, rc, view, name, renderer, request_methods, default_content_type, default_response_content_type, options): for request_method in request_methods: opts = options.copy() vw = view if vw is None \ or (isinstance(view, type) and issubclass(view, RepresentingResourceView)): register_sub_views = name == '' kw = dict( default_content_type=default_content_type, default_response_content_type=default_response_content_type, convert_response=renderer is None) if view is None: # Attempt to guess a default view. We register a factory # so we can pass additional constructor arguments. if provides_member_resource(rc): if request_method == 'GET': vw = self.__make_view_factory(GetMemberView, kw) elif request_method == 'PUT': vw = self.__make_view_factory(PutMemberView, kw) elif request_method == 'DELETE': # The DELETE view is special as it does not have # to deal with representations. vw = DeleteMemberView register_sub_views = False elif request_method == 'FAKE_PUT': request_method = 'POST' opts['header'] = 'X-HTTP-Method-Override:PUT' vw = self.__make_view_factory(PutMemberView, kw) elif request_method == 'FAKE_DELETE': request_method = 'POST' opts['header'] = 'X-HTTP-Method-Override:DELETE' vw = DeleteMemberView register_sub_views = False else: raise ValueError('Autodetection for member ' 'resource views requires ' '"GET", "PUT", "DELETE", ' '"FAKE_PUT", or "FAKE_DELETE" ' 'as request method.') else: if request_method == 'GET': vw = \ self.__make_view_factory(GetCollectionView, kw) elif request_method == 'POST': vw = \ self.__make_view_factory(PostCollectionView, kw) else: raise ValueError('Autodetection for collectioon ' 'resource views requires ' '"GET" or "POST" ' 'as request method.') else: vw = self.__make_view_factory(view, kw) else: register_sub_views = False vnames = set([name]) if register_sub_views: # Add sub-views for registered representer names if this view # uses representers (and is not a named view itself). vnames.update(get_registered_representer_names()) for vname in vnames: self.add_view(context=rc, view=vw, renderer=renderer, request_method=request_method, name=vname, **opts)
def __add_resource_view(self, rc, view, name, renderer, request_methods, default_content_type, default_response_content_type, enable_messaging, options): for request_method in request_methods: opts = options.copy() vw = view if vw is None \ or (isinstance(view, type) and issubclass(view, RepresentingResourceView)): register_sub_views = name == '' kw = dict(default_content_type=default_content_type, default_response_content_type= default_response_content_type, enable_messaging=enable_messaging, convert_response=renderer is None) if view is None: # Attempt to guess a default view. We register a factory # so we can pass additional constructor arguments. if provides_member_resource(rc): if request_method == RequestMethods.GET: vw = self.__make_view_factory(GetMemberView, kw) elif request_method == RequestMethods.PUT: vw = self.__make_view_factory(PutMemberView, kw) elif request_method == RequestMethods.PATCH: vw = self.__make_view_factory(PatchMemberView, kw) elif request_method == RequestMethods.DELETE: # The DELETE view is special as it does not have # to deal with representations. vw = DeleteMemberView register_sub_views = False elif request_method == RequestMethods.FAKE_PUT: request_method = RequestMethods.POST opts['header'] = 'X-HTTP-Method-Override:PUT' vw = self.__make_view_factory(PutMemberView, kw) elif request_method == RequestMethods.FAKE_PATCH: request_method = RequestMethods.POST opts['header'] = 'X-HTTP-Method-Override:PATCH' vw = self.__make_view_factory(PatchMemberView, kw) elif request_method == RequestMethods.FAKE_DELETE: request_method = RequestMethods.POST opts['header'] = 'X-HTTP-Method-Override:DELETE' vw = DeleteMemberView register_sub_views = False else: mb_req_methods = [rm for rm in RequestMethods if not rm == 'POST'] raise ValueError('Autodetection for member ' 'resource views requires ' 'one of %s as request method.' % str(mb_req_methods)) else: if request_method == RequestMethods.GET: vw = \ self.__make_view_factory(GetCollectionView, kw) elif request_method == RequestMethods.POST: vw = \ self.__make_view_factory(PostCollectionView, kw) else: coll_req_methods = [RequestMethods.GET, RequestMethods.POST] raise ValueError('Autodetection for collectioon ' 'resource views requires ' 'one of %s as request method.' % str(coll_req_methods)) else: vw = self.__make_view_factory(view, kw) else: register_sub_views = False vnames = set([name]) if register_sub_views: # Add sub-views for registered representer names if this view # uses representers (and is not a named view itself). vnames.update(get_registered_representer_names()) for vname in vnames: self.add_view(context=rc, view=vw, renderer=renderer, request_method=request_method, name=vname, **opts)