def component_handler(request, usage_key_string, handler, suffix=''): """ Dispatch an AJAX action to an xblock Args: usage_id: The usage-id of the block to dispatch to handler (str): The handler to execute suffix (str): The remainder of the url to be passed to the handler Returns: :class:`django.http.HttpResponse`: The response from the handler, converted to a django response """ usage_key = UsageKey.from_string(usage_key_string) # Let the module handle the AJAX req = django_to_webob_request(request) asides = [] try: if isinstance(usage_key, (AsideUsageKeyV1, AsideUsageKeyV2)): descriptor = modulestore().get_item(usage_key.usage_key) aside_instance = get_xblock_aside_instance(usage_key) asides = [aside_instance] if aside_instance else [] resp = aside_instance.handle(handler, req, suffix) else: descriptor = modulestore().get_item(usage_key) descriptor.xmodule_runtime = StudioEditModuleRuntime(request.user) resp = descriptor.handle(handler, req, suffix) except NoSuchHandlerError: log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True) raise Http404 # unintentional update to handle any side effects of handle call # could potentially be updating actual course data or simply caching its values modulestore().update_item(descriptor, request.user.id, asides=asides) return webob_to_django_response(resp)