diff --git a/common/lib/xmodule/xmodule/abtest_module.py b/common/lib/xmodule/xmodule/abtest_module.py index ceca6ff9ed..7080682172 100644 --- a/common/lib/xmodule/xmodule/abtest_module.py +++ b/common/lib/xmodule/xmodule/abtest_module.py @@ -47,11 +47,9 @@ class ABTestModule(XModule): def get_shared_state(self): return json.dumps({'group': self.group}) - - def displayable_items(self): - child_locations = self.definition['data']['group_content'][self.group] - children = [self.system.get_module(loc) for loc in child_locations] - return [c for c in children if c is not None] + + def get_children_locations(self): + return self.definition['data']['group_content'][self.group] # TODO (cpennington): Use Groups should be a first class object, rather than being @@ -158,3 +156,7 @@ class ABTestDescriptor(RawDescriptor, XmlDescriptor): group_elem.append(etree.fromstring(child.export_to_xml(resource_fs))) return xml_object + + + def has_dynamic_children(self): + return True diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index e21e858baa..8846926e05 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -219,13 +219,28 @@ class XModule(HTMLSnippet): Return module instances for all the children of this module. ''' if self._loaded_children is None: - child_locations = self.definition.get('children', []) + child_locations = self.get_children_locations() children = [self.system.get_module(loc) for loc in child_locations] # get_module returns None if the current user doesn't have access # to the location. self._loaded_children = [c for c in children if c is not None] return self._loaded_children + + def get_children_locations(self): + ''' + Returns the locations of each of child modules. + + Overriding this changes the behavior of get_children and + anything that uses get_children, such as get_display_items. + + This method will not instantiate the modules of the children + unless absolutely necessary, so it is cheaper to call than get_children + + These children will be the same children returned by the + descriptor unless descriptor.has_dynamic_children() is true. + ''' + return self.definition.get('children', []) def get_display_items(self): ''' @@ -489,6 +504,18 @@ class XModuleDescriptor(Plugin, HTMLSnippet): self, metadata=self.metadata ) + + + def has_dynamic_children(self): + """ + Returns True if this descriptor has dynamic children for a given + student when the module is created. + + Returns False if the children of this descriptor are the same + children that the module will return for any student. + """ + return False + # ================================= JSON PARSING =========================== @staticmethod