def api_add_inheritance_data(request, **kwargs): if request.method != "POST": raise QError("api_add_inheritance_data can only accept POST requests") instance_key = get_key_from_request(request) existing_inheritance_data = get_cached_inheritance_data(instance_key) inheritance_data = dict(request.POST) # TODO: I HAVE NO IDEA WHY VALUES IN THE POST DICTIONARY ARE ALL LISTS?!? for k, v in inheritance_data.iteritems(): if isinstance(v, list): inheritance_data[k] = v[0] if not existing_inheritance_data: set_cached_inheritance_data(inheritance_data) else: existing_inheritance_data.update(inheritance_data) set_cached_inheritance_data(existing_inheritance_data) response = HttpResponse(status=200) return response
def q_realization_remove_relationship_value(request): # check the request was valid... valid_request, msg = validate_request(request) if not valid_request: return HttpResponseForbidden(msg) target_index = request.POST.get("target_index") target_key = request.POST.get("target_key") property_key = request.POST.get("key") session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) cached_realizations = get_cached_object(request.session, cached_realizations_key) if not cached_realizations: msg = "unable to locate cached_realizations" return HttpResponseBadRequest(msg) # do some sanity checks... # check the realization to remove from exists... property_realization = get_property_realization_by_key(property_key, cached_realizations) if not property_realization: msg = "unable to find a QPropertyRealization with a key of '{0}'".format(property_key) return HttpResponseBadRequest(msg) # check that the target to remove exists... target_realizations = property_realization.relationship_values(manager="allow_unsaved_relationship_values_manager").filter_potentially_unsaved(key=target_key) if len(target_realizations) != 1: msg = "unable to find a QModelProxy with a key of '{0}'".format(target_key) return HttpResponseBadRequest(msg) target_realization = target_realizations[0] # check that it makes sense to remove this target... if property_realization.relationship_values(manager="allow_unsaved_relationship_values_manager").count() <= property_realization.cardinality_min: msg = "you have cannot remove this many QModelRealizations from this this QPropertyRealization" return HttpResponseBadRequest(msg) # check the user has permission to modify the realization... current_user = request.user project = cached_realizations.project if project.authenticated: if not current_user.is_authenticated() or not is_member_of(current_user, project): msg = "{0} does not have permission to modify a realization".format(current_user) return HttpResponseForbidden(msg) # ...okay, sanity checks are over # now remove the target... property_realization.relationship_values(manager="allow_unsaved_relationship_values_manager").remove_potentially_unsaved(target_realization) if target_realization.is_existing: target_realization.delete() request.session[cached_realizations_key] = cached_realizations # finally return a success msg... msg = "Successfully removed object" return JsonResponse({"msg": msg})
def q_realization_add_relationship_value(request): valid_request, msg = validate_request(request) if not valid_request: return HttpResponseForbidden(msg) target_proxy_id = request.POST.get("target_proxy_id") property_key = request.POST.get("key") session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) cached_realizations = get_cached_object(request.session, cached_realizations_key) if not cached_realizations: msg = "unable to locate cached_realizations" raise QError(msg) property = get_property_realization_by_fn( lambda r: r.get_key() == property_key, cached_realizations ) if not property: raise QError("unable to find property w/ key='{0}'".format(property_key)) target_proxy = QModelProxy.objects.get(id=target_proxy_id) new_model_realization = get_new_realizations( project=cached_realizations.project, ontology=cached_realizations.ontology, model_proxy=target_proxy, key=target_proxy.name, ) # double-check that adding this model to this property makes sense... assert target_proxy in property.proxy.relationship_target_models.all() assert property.get_cardinality_max() == '*' or property.relationship_values(manager="allow_unsaved_relationship_values_manager").count() < int(property.get_cardinality_max()) # add the model... property.relationship_values(manager="allow_unsaved_relationship_values_manager").add_potentially_unsaved(new_model_realization) with allow_unsaved_fk(QModel, ["relationship_property"]): # in theory, Django doesn't store unsaved relationship # the custom manager above gets around this for the m2m relationship (property to model) and it is what I ought to use # however, in order to work my way up the realization hierarchy I need access to the reverse of that relationship # which is a fk relationship; hence this extra bit of code (which only exists so that "model_realizations.py#QRealization.get_parent_model_realization" works) new_model_realization.relationship_property = property # re-cache the changed realizations... request.session[cached_realizations_key] = cached_realizations # and return a serialized version of that model... new_model_realization_serialization = serialize_new_realizations(new_model_realization) return JsonResponse(new_model_realization_serialization)
def get_cached_customization(request): assert request.method == "GET" try: session_key = get_key_from_request(request) cached_customization_set_key = "{0}_customization_set".format(session_key) customization_set = get_cached_object(request.session, cached_customization_set_key) except QError: # TODO: THIS SECTION JUST EXISTS FOR DEBUGGING session_key = "cef3f8d5-f8f9-4490-b396-3c8e7e25aece" cached_customization_set_key = "{0}_customization_set".format(session_key) customization_set = get_cached_object(request.session, cached_customization_set_key) serialized_customization_set = serialize_customization_set(customization_set) return Response(serialized_customization_set)
def get_cached_customizations(request): assert request.method == "GET" try: session_key = get_key_from_request(request) cached_customizations_key = "{0}_customizations".format(session_key) customizations = get_cached_object(request.session, cached_customizations_key) except QError: # ** THIS SECTION JUST EXISTS FOR DEBUGGING ** # import ipdb; ipdb.set_trace() session_key = "d33e5c1c-8c86-4d7f-bf44-b479745411d1" cached_customizations_key = "{0}_customizations".format(session_key) customizations = get_cached_object(request.session, cached_customizations_key) serialized_customizations = serialize_customizations(customizations) return Response(serialized_customizations)
def get_cached_realizations(request): assert request.method == "GET" try: session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) realizations = get_cached_object(request.session, cached_realizations_key) except QError: # ** THIS SECTION JUST EXISTS FOR DEBUGGING ** import ipdb; ipdb.set_trace() session_key = "25b9d538-8b22-4cd1-b668-f934b716f323" cached_realizations_key = "{0}_realizations".format(session_key) realizations = get_cached_object(request.session, cached_realizations_key) serialized_realizations = serialize_realizations(realizations) return Response(serialized_realizations)
def get_cached_customizations(request): assert request.method == "GET" try: session_key = get_key_from_request(request) cached_customizations_key = "{0}_customizations".format(session_key) customizations = get_cached_object(request.session, cached_customizations_key) except QError: # ** THIS SECTION JUST EXISTS FOR DEBUGGING ** import ipdb ipdb.set_trace() session_key = "36493064-6c85-4e7b-af9b-bd2132b4d927" cached_customizations_key = "{0}_customizations".format(session_key) customizations = get_cached_object(request.session, cached_customizations_key) serialized_customizations = serialize_new_customizations(customizations) return Response(serialized_customizations)
def q_realization_remove_relationship_value(request): valid_request, msg = validate_request(request) if not valid_request: return HttpResponseForbidden(msg) target_index = int(request.POST.get("target_index")) property_key = request.POST.get("key") session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) cached_realizations = get_cached_object(request.session, cached_realizations_key) if not cached_realizations: msg = "unable to locate cached_realizations" raise QError(msg) property = get_property_realization_by_fn( lambda r: r.get_key() == property_key, cached_realizations ) if not property: raise QError("unable to find property w/ key='{0}'".format(property_key)) # remove the model... try: target_to_remove = property.relationship_values(manager="allow_unsaved_relationship_values_manager").all()[target_index] property.relationship_values(manager="allow_unsaved_relationship_values_manager").remove_potentially_unsaved(target_to_remove) if target_to_remove.is_existing(): target_to_remove.delete() except IndexError: raise QError("unable to find target of {0} at index {1}".format(property, target_index)) # re-cache the changed realizations... request.session[cached_realizations_key] = cached_realizations # and return a success msg... msg = "Successfully removed object" # (don't need to explicitly render this msg using Django messaging framework) # (b/c it will be obvious to the user that a model was removed since a subform will dissappear) # (and, anyway, there is no corresponding msg that is used when a model is added to a property) # messages.add_message(request, messages.SUCCESS, msg) return JsonResponse({"msg": msg})
def q_load_section(request, section_type=None): valid_request, msg = validate_request(request) if not valid_request: return HttpResponseForbidden(msg) try: section_info = SECTION_MAP[section_type] except KeyError: msg = "I don't know how to render a section w/ type '{0}'".format(section_type) return HttpResponseBadRequest(msg) model_index = request.POST.get("index") model_key = request.POST.get("key") model_scope = request.POST.get("scope") session_key = get_key_from_request(request) cached_models_key = section_info["cached_models_key"].format(session_key=session_key) cached_models = get_cached_object(request.session, cached_models_key) if not cached_models: msg = "unable to locate cached_models" raise QError(msg) get_model_fn = section_info["get_model_fn"] model = get_model_fn(model_key, cached_models) if not model: raise QError("unable to find instance w/ key='{0}'".format(model_key)) template_context = {} for context_key, context_value in section_info.get("template_context").iteritems(): form_class = context_value["class"] template_context[context_key] = form_class( instance=model, name=context_value["name"].format(safe_key=model_key.replace('-', '_')), scope_prefix=context_value["scope_prefix"].format(index=model_index) ) template = "{0}/sections/{1}".format(APP_LABEL, section_info["template"]) return render_to_response(template, template_context, context_instance=RequestContext(request))
def api_get_new_edit_form_section(request, project_name, section_key, **kwargs): # check the arguments to the view, # and parse the section key (validity, version, model_proxy, vocabulary, component_proxy, property_type, category_proxy, property_proxy, model_customizer, vocabularies, msg) = \ validate_edit_view_arguments(project_name, section_key) if not validity: return questionnaire_error(request, msg) # get (or set) models from the cache... session_key = get_key_from_request(request) cached_customization_set_key = "{0}_customization_set".format(session_key) cached_proxy_set_key = "{0}_proxy_set".format(session_key) cached_realization_set_key = "{0}_realization_set".format(session_key) customization_set = get_or_create_cached_object(request.session, cached_customization_set_key, get_existing_customization_set, **{ "project": model_customizer.project, "ontology": version, "proxy": model_customizer.proxy, "customization_name": model_customizer.name, } ) customization_set = convert_customization_set(customization_set) customization_set["scientific_category_customizers"] = get_joined_keys_dict(customization_set["scientific_category_customizers"]) customization_set["scientific_property_customizers"] = get_joined_keys_dict(customization_set["scientific_property_customizers"]) proxy_set = get_or_create_cached_object(request.session, cached_proxy_set_key, get_existing_proxy_set, **{ "ontology": version, "proxy": model_proxy, "vocabularies": vocabularies, } ) proxy_set = convert_proxy_set(proxy_set) realization_set = get_or_create_cached_object(request.session, cached_realization_set_key, get_new_realization_set, **{ "project": model_customizer.project, "ontology": version, "model_proxy": proxy_set["model_proxy"], "standard_property_proxies": proxy_set["standard_property_proxies"], "scientific_property_proxies": proxy_set["scientific_property_proxies"], "model_customizer": customization_set["model_customizer"], "vocabularies": vocabularies, } ) inheritance_data = get_cached_inheritance_data(session_key) # now create the formsets... (model_formset, standard_properties_formsets, scientific_properties_formsets) = \ create_new_edit_forms_from_models( realization_set["models"], customization_set["model_customizer"], realization_set["standard_properties"], customization_set["standard_property_customizers"], realization_set["scientific_properties"], customization_set["scientific_property_customizers"], inheritance_data=inheritance_data, ) # now get some things that were previously computed in the master template # or in loops that I need to recreate for the individual sections section_keys = section_key.split('|') model_key = u"%s_%s" % (section_keys[2], section_keys[3]) _dict = { "vocabularies": vocabularies, "model_customizer": model_customizer, "model_formset": model_formset, "standard_properties_formsets": standard_properties_formsets, "scientific_properties_formsets": scientific_properties_formsets, "section_parameters": { "model_form": get_form_by_prefix(model_formset, model_key), "standard_property_formset": standard_properties_formsets[model_key], "scientific_property_formset": scientific_properties_formsets[model_key], "active_standard_categories_and_properties": get_active_standard_categories_and_properties(customization_set["model_customizer"]), "active_scientific_categories_and_properties": get_active_scientific_categories_and_properties_by_key(customization_set["model_customizer"], model_key), }, } template = get_edit_section_template_path(property_proxy, property_type, category_proxy) return render_to_response(template, _dict, context_instance=RequestContext(request))
def q_realization_add_relationship_value(request): # check the request was valid... valid_request, msg = validate_request(request) if not valid_request: return HttpResponseForbidden(msg) target_proxy_id = request.POST.get("target_proxy_id") property_key = request.POST.get("key") session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) cached_realizations = get_cached_object(request.session, cached_realizations_key) if not cached_realizations: msg = "unable to locate cached_realizations" return HttpResponseBadRequest(msg) # do some sanity checks... # check the realization to add to exists... property_realization = get_property_realization_by_key(property_key, cached_realizations) if not property_realization: msg = "unable to find a QPropertyRealization with a key of '{0}'".format(property_key) return HttpResponseBadRequest(msg) # check that the target to add exists... try: target_proxy = QModelProxy.objects.get(id=target_proxy_id) except QModelProxy.DoesNotExist: msg = "unable to find a QModelProxy with an id of '{0}'".format(target_proxy_id) return HttpResponseBadRequest(msg) # check that it makes sense to add this target... if target_proxy not in property_realization.proxy.relationship_target_models.all(): msg = "you are trying to add the wrong type of QModelRealization to this QPropertyRealization" return HttpResponseBadRequest(msg) if (not property_realization.is_infinite) and (property_realization.relationship_values(manager="allow_unsaved_relationship_values_manager").count() >= property_realization.cardinality_max): msg = "you have already added the maximum amount of QModelRealizations to this QPropertyRealization" return HttpResponseBadRequest(msg) # check the user has permission to modify the realization... current_user = request.user project = cached_realizations.project if project.authenticated: if not current_user.is_authenticated() or not is_member_of(current_user, project): msg = "{0} does not have permission to modify a realization".format(current_user) return HttpResponseForbidden(msg) # ...okay, sanity checks are over # now create the model... new_model_realization = get_new_realizations( project=project, ontology=target_proxy.ontology, model_proxy=target_proxy, key=target_proxy.name, ) # now add the model... property_realization.relationship_values(manager="allow_unsaved_relationship_values_manager").add_potentially_unsaved(new_model_realization) with allow_unsaved_fk(QModelRealization, ["relationship_property"]): # the custom manager above ("allow_unsaved_relationship_values_manager") lets me cope w/ an unsaved m2m relationship - it is what I ought to use # however, some fns ("QRealization.get_root_realization") needs access to the reverse of that relationship; hence this extra bit of code new_model_realization.relationship_property = property_realization request.session[cached_realizations_key] = cached_realizations # finally return a serialized version of that model... new_model_realization_serialization = serialize_realizations(new_model_realization) return JsonResponse(new_model_realization_serialization)
def q_customize_new(request, project_name=None, ontology_key=None, document_type=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, proxy, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): next_page = "/login/?next=%s" % request.path return HttpResponseRedirect(next_page) if not is_admin_of(current_user, project): next_page = "/%s/" % project_name msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get the set of vocabularies that apply to this project/ontology/proxy... vocabularies = project.vocabularies.filter(document_type__iexact=document_type) # get (or set) customization objects from the cache... session_key = get_key_from_request(request) cached_customization_set_key = "{0}_customization_set".format(session_key) customization_set = get_or_create_cached_object(request.session, cached_customization_set_key, get_new_customization_set, **{ "project": project, "ontology": ontology, "proxy": proxy, "vocabularies": vocabularies, } ) model_customization = customization_set["model_customization"] # I am only generating the model_customization_form at this top-level # all other forms (and formsets) are genearted as needed via the "load_section" view # called by the "section" directive according to the load-on-demand paradigm model_customization_form = QModelCustomizationForm( instance=model_customization, form_name="model_customization_form", # prefix=?!?, scope_prefix="model_customization", ) # else: # request.method == "POST" # # # IN THEORY, I NEVER ENTER THIS BRANCH B/C ALL FORM SUBMISSION IS DONE VIA REST / ANGULAR # # BUT I'M KEEPING THIS CODE HERE IN-CASE I NEED TO REFER TO IT LATER # # data = request.POST.copy() # sometimes I need to alter the data for unloaded forms; # # this cannot be done on the original (immutable) QueryDict # # model_customization_form = QModelCustomizationForm( # data, # instance=customization_set["model_customization"], # # prefix=?!?, # scope_prefix="model_customization", # form_name="model_customization_form", # ) # # if model_customization_form.is_valid(): # customization = model_customization_form.save() # messages.add_message(request, messages.SUCCESS, "Successfully saved customization '%s'." % customization.name) # customize_existing_url = reverse("customize_existing", kwargs={ # "project_name": project_name, # "ontology_key": ontology_key, # "document_type": document_type, # "customizer_name": customization.name, # }) # return HttpResponseRedirect(customize_existing_url) # # else: # # messages.add_message(request, messages.ERROR, "Failed to save customization.") # work out the various paths, # so that angular can reload things as needed view_url = request.path view_url_sections = [section for section in view_url.split('/') if section] view_url_dirname = '/'.join(view_url_sections[:]) api_url = reverse("customization-list", kwargs={}) api_url_sections = [section for section in api_url.split('/') if section] api_url_dirname = '/'.join(api_url_sections[:]) # gather all the extra information required by the template _dict = { "session_key": session_key, "view_url_dirname": "/{0}/".format(view_url_dirname), "api_url_dirname": "/{0}/".format(api_url_dirname), "ontology": ontology, "proxy": proxy, "project": project, "vocabularies": vocabularies, "customization": model_customization, "model_customization_form": model_customization_form, } return render_to_response('questionnaire/q_customize.html', _dict, context_instance=context)
def q_customize_existing(request, project_name=None, ontology_key=None, document_type=None, customization_name=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, proxy, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) if project.authenticated: current_user = request.user if not current_user.is_authenticated(): next_page = "/login/?next=%s" % request.path return HttpResponseRedirect(next_page) if not is_admin_of(current_user, project): next_page = "/%s/" % project_name msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) customization objects from the cache... # note that unlike in "q_customize_new" above, this bit is enclosed in a try/catch block # this is to deal w/ the possibility of an invalid customization_name try: session_key = get_key_from_request(request) cached_customization_set_key = "{0}_customization_set".format(session_key) customization_set = get_or_create_cached_object(request.session, cached_customization_set_key, get_existing_customization_set, **{ "project": project, "ontology": ontology, "proxy": proxy, "customization_name": customization_name, } ) except ObjectDoesNotExist: msg = "Cannot find the customization '{0}' for that project/ontology/model combination.".format(customization_name) return q_error(request, msg) model_customization = customization_set["model_customization"] # I am only generating the model_customization_form at this top-level # all other forms (and formsets) are generated as needed via the "load_section" view # called by the "section" directive according to the load-on-demand paradigm model_customization_form = QModelCustomizationForm( instance=model_customization, form_name="model_customization_form", # prefix=?!?, scope_prefix="model_customization", ) # work out the various paths, # so that angular can reload things as needed view_url = request.path view_url_sections = [section for section in view_url.split('/') if section] view_url_dirname = '/'.join(view_url_sections[:-1]) api_url = reverse("customization-detail", kwargs={"pk": model_customization.pk}) api_url_sections = [section for section in api_url.split('/') if section] api_url_dirname = '/'.join(api_url_sections[:-1]) # gather all the extra information required by the template _dict = { "session_key": session_key, "view_url_dirname": "/{0}/".format(view_url_dirname), "api_url_dirname": "/{0}/".format(api_url_dirname), "ontology": ontology, "proxy": proxy, "project": project, "vocabularies": [v.vocabulary for v in customization_set["vocabulary_customizations"]], "customization": model_customization, "model_customization_form": model_customization_form, } return render_to_response('questionnaire/q_customize.html', _dict, context_instance=context)
def q_customize_new(request, project_name=None, ontology_key=None, document_type=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) current_user = request.user if project.authenticated: if not current_user.is_authenticated(): next_page = "/login/?next=%s" % request.path return HttpResponseRedirect(next_page) if not is_admin_of(current_user, project): next_page = "/%s/" % project_name msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) customization objects from the cache... session_key = get_key_from_request(request) cached_customizations_key = "{0}_customizations".format(session_key) model_customization = get_or_create_cached_object(request.session, cached_customizations_key, get_new_customizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "key": model_proxy.name, } ) model_customization_key = model_customization.get_key() if current_user.is_authenticated(): set_owner(model_customization, evaluate_lazy_object(current_user)) # I generate the model_customization_form at this top-level # all other forms are generated as needed via the "load_section" view # which is called by the "section" directive according to the load-on-demand paradigm model_customization_form_class = MODEL_CUSTOMIZATION_FORM_MAP["form_class"] model_customization_form = model_customization_form_class( instance=model_customization, form_name=MODEL_CUSTOMIZATION_FORM_MAP["form_name"].format(safe_key=model_customization_key.replace('-', '_')), # prefix=?!? scope_prefix=MODEL_CUSTOMIZATION_FORM_MAP["form_scope_prefix"], ) # work out the various paths, # so that ng can reload things as needed view_url = request.path view_url_sections = [section for section in view_url.split('/') if section] view_url_dirname = '/'.join(view_url_sections[:]) api_url = reverse("customization-list", kwargs={}) api_url_sections = [section for section in api_url.split('/') if section] api_url_dirname = '/'.join(api_url_sections[:]) # gather all the extra information required by the template _dict = { "session_key": session_key, "view_url_dirname": "/{0}/".format(view_url_dirname), "api_url_dirname": "/{0}/".format(api_url_dirname), "project": project, "ontology": ontology, "proxy": model_proxy, "customization": model_customization, "form": model_customization_form, } return render_to_response('questionnaire/q_customize.html', _dict, context_instance=context)
def q_edit_new(request, project_name=None, ontology_key=None, document_type=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, model_customization, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) current_user = request.user if project.authenticated: if not current_user.is_authenticated(): next_page = add_parameters_to_url(reverse("account_login"), next=request.path) return HttpResponseRedirect(next_page) if not is_user_of(current_user, project): next_page = reverse("project", kwargs={"project_name": project_name}) msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) realization objects from the cache... session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) model_realization = get_or_create_cached_object(request.session, cached_realizations_key, get_new_realizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "key": model_proxy.name, } ) if current_user.is_authenticated(): set_owner(model_realization, evaluate_lazy_object(current_user)) model_realization.is_root = True # TODO: COME UP W/ A BETTER WAY OF DEALING W/ "is_root" # no forms are created here, # instead the load-on-demand paradigm is used, # work out various paths, so that ng can reload things as needed... view_url_dirname = request.path.rsplit('/', 1)[0] api_url_dirname = reverse("realization-list").rsplit('/', 1)[0] # gather all the extra information required by the template... template_context = { "project": project, "ontology": ontology, "proxy": model_proxy, "view_url_dirname": view_url_dirname, "api_url_dirname": api_url_dirname, "session_key": session_key, "customization": model_customization, "realization": model_realization, "read_only": "false", # passing "false" instead of False b/c this is a JS variable } return render_to_response('questionnaire/q_edit.html', template_context, context_instance=context)
def q_customize_new(request, project_name=None, ontology_key=None, document_type=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) current_user = request.user if project.authenticated: if not current_user.is_authenticated(): next_page = add_parameters_to_url(reverse("account_login"), next=request.path) return HttpResponseRedirect(next_page) if not is_admin_of(current_user, project): next_page = reverse("project", kwargs={"project_name": project_name}) msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) customization objects from the cache... session_key = get_key_from_request(request) cached_customizations_key = "{0}_customizations".format(session_key) model_customization = get_or_create_cached_object(request.session, cached_customizations_key, get_new_customizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, # "key": model_proxy.name, "key": model_proxy.key, } ) if current_user.is_authenticated(): set_owner(model_customization, evaluate_lazy_object(current_user)) # setup top-level form... # (subforms are handled by the load-on-demand paradigm) model_customization_form_class = MODEL_CUSTOMIZATION_FORM_MAP["form_class"] model_customization_form = model_customization_form_class( instance=model_customization, form_name=MODEL_CUSTOMIZATION_FORM_MAP["form_name"].format(safe_key=model_customization.key.replace('-', '_')), scope_prefix=MODEL_CUSTOMIZATION_FORM_MAP["form_scope_prefix"], # prefix=?!? ) # work out various paths, so that ng can reload things as needed... view_url_dirname = request.path.rsplit('/', 1)[0] api_url_dirname = reverse("customization-list").rsplit('/', 1)[0] # gather all the extra information required by the template... template_context = { "project": project, "ontology": ontology, "proxy": model_proxy, "view_url_dirname": view_url_dirname, "api_url_dirname": api_url_dirname, "session_key": session_key, "customization": model_customization, "form": model_customization_form, } return render_to_response('questionnaire/q_customize.html', template_context, context_instance=context)
def q_view_existing(request, project_name=None, ontology_key=None, document_type=None, realization_pk=None): """ this is exactly the same as "q_edit_existing" except: there are no authentication checks, the template_context & template are different. :param request: :param project_name: :param ontology_key: :param document_type: :param realization_pk: :return: """ # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, model_customization, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # no need to check authentication # get (or set) realization objects from the cache... # note that unlike in "q_edit_new" above, this bit is enclosed in a try/catch block try: session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) model_realization = get_or_create_cached_object(request.session, cached_realizations_key, get_existing_realizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "model_id": realization_pk } ) except ObjectDoesNotExist: msg = "Cannot find a document with an id of '{0}' for that project/ontology/document type combination.".format(realization_pk) return q_error(request, msg) # no forms are created here, # instead the load-on-demand paradigm is used, # work out various paths, so that ng can reload things as needed... # (notice these are slightly different than in "q_edit_new" above view_url_dirname = request.path.rsplit('/', 1)[0] api_url_dirname = reverse("realization-detail", kwargs={"pk": model_realization.pk}).rsplit('/', 2)[0] # gather all the extra information required by the template... template_context = { "project": project, "ontology": ontology, "proxy": model_proxy, "view_url_dirname": view_url_dirname, "api_url_dirname": api_url_dirname, "session_key": session_key, "customization": model_customization, "realization": model_realization, "read_only": "true", # passing "true" instead of True b/c this is a JS variable } return render_to_response('questionnaire/q_view.html', template_context, context_instance=context)
def q_edit_existing(request, project_name=None, ontology_key=None, document_type=None, realization_pk=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, model_customization, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) current_user = request.user if project.authenticated: if not current_user.is_authenticated(): next_page = add_parameters_to_url(reverse("account_login"), next=request.path) return HttpResponseRedirect(next_page) if not is_user_of(current_user, project): next_page = reverse("project", kwargs={"project_name": project_name}) msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) realization objects from the cache... # note that unlike in "q_edit_new" above, this bit is enclosed in a try/catch block try: session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) model_realization = get_or_create_cached_object(request.session, cached_realizations_key, get_existing_realizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "model_id": realization_pk } ) except ObjectDoesNotExist: msg = "Cannot find a document with an id of '{0}' for that project/ontology/document type combination.".format(realization_pk) return q_error(request, msg) # no forms are created here, # instead the load-on-demand paradigm is used, # work out various paths, so that ng can reload things as needed... # (notice these are slightly different than in "q_edit_new" above view_url_dirname = request.path.rsplit('/', 1)[0] api_url_dirname = reverse("realization-detail", kwargs={"pk": model_realization.pk}).rsplit('/', 2)[0] # gather all the extra information required by the template... template_context = { "project": project, "ontology": ontology, "proxy": model_proxy, "view_url_dirname": view_url_dirname, "api_url_dirname": api_url_dirname, "session_key": session_key, "customization": model_customization, "realization": model_realization, "read_only": "false", # passing "false" instead of False b/c this is a JS variable } return render_to_response('questionnaire/q_edit.html', template_context, context_instance=context)
def api_get_existing_edit_form_section(request, project_name, section_key, model_id, **kwargs): # check the arguments to the view, # and parse the section key (validity, version, model_proxy, vocabulary, component_proxy, property_type, category_proxy, property_proxy, model_customizer, vocabularies, msg) = \ validate_edit_view_arguments(project_name, section_key) if not validity: return questionnaire_error(request, msg) # and check requested model(s)... # (even though this view may return a small section for a single model, # the full set of models is needed to re-create the forms properly) try: root_model = MetadataModel.objects.get(pk=model_id) except MetadataModel.DoesNotExist: msg = "Cannot find the specified model. Please try again." return questionnaire_error(request, msg) if not root_model.is_root: # TODO: DEAL W/ THIS USE-CASE msg = "Currently only root models can be viewed. Please try again." return questionnaire_error(request, msg) # get (or set) models from the cache... session_key = get_key_from_request(request) cached_customization_set_key = "{0}_customization_set".format(session_key) cached_proxy_set_key = "{0}_proxy_set".format(session_key) cached_realization_set_key = "{0}_realization_set".format(session_key) customization_set = get_or_create_cached_object(request.session, cached_customization_set_key, get_existing_customization_set, **{ "project": model_customizer.project, "ontology": version, "proxy": model_customizer.proxy, "customization_name": model_customizer.name, } ) customization_set = convert_customization_set(customization_set) customization_set["scientific_category_customizers"] = get_joined_keys_dict(customization_set["scientific_category_customizers"]) customization_set["scientific_property_customizers"] = get_joined_keys_dict(customization_set["scientific_property_customizers"]) proxy_set = get_or_create_cached_object(request.session, cached_proxy_set_key, get_existing_proxy_set, **{ "ontology": version, "proxy": model_proxy, "vocabularies": vocabularies, } ) proxy_set = convert_proxy_set(proxy_set) realization_set = get_or_create_cached_object(request.session, cached_realization_set_key, get_existing_realization_set, **{ "models": root_model.get_descendants(include_self=True), "model_customizer": customization_set["model_customizer"], "vocabularies": vocabularies, } ) inheritance_data = get_cached_inheritance_data(session_key) # now create the formsets... (model_formset, standard_properties_formsets, scientific_properties_formsets) = \ create_existing_edit_forms_from_models( realization_set["models"], customization_set["model_customizer"], realization_set["standard_properties"], customization_set["standard_property_customizers"], realization_set["scientific_properties"], customization_set["scientific_property_customizers"], inheritance_data=inheritance_data ) # now get some things that were previously computed in the master template # or in loops that I need to recreate for the individual sections section_keys = section_key.split('|') model_key = u"%s_%s" % (section_keys[2], section_keys[3]) _dict = { "vocabularies": vocabularies, "model_customizer": model_customizer, "model_formset": model_formset, "standard_properties_formsets": standard_properties_formsets, "scientific_properties_formsets": scientific_properties_formsets, "section_parameters": { "model_form": get_form_by_prefix(model_formset, model_key), "standard_property_formset": standard_properties_formsets[model_key], "scientific_property_formset": scientific_properties_formsets[model_key], "active_standard_categories_and_properties": get_active_standard_categories_and_properties(customization_set["model_customizer"]), "active_scientific_categories_and_properties": get_active_scientific_categories_and_properties_by_key(customization_set["model_customizer"], model_key), }, } template = get_edit_section_template_path(property_proxy, property_type, category_proxy) return render_to_response(template, _dict, context_instance=RequestContext(request))
def q_view_existing(request, project_name=None, ontology_key=None, document_type=None, realization_pk=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, model_customization, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # no need to check authentication # get (or set) realization objects from the cache... # note that unlike in "q_edit_new" above, this bit is enclosed in a try/catch block # this is to deal w/ the possibility of an invalid realization_pk try: session_key = get_key_from_request(request) cached_realizations_key = "{0}_realizations".format(session_key) model_realization = get_or_create_cached_object(request.session, cached_realizations_key, get_existing_realizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "model_id": realization_pk, } ) except ObjectDoesNotExist: msg = "Cannot find a document with an id of '{0}' for that project/ontology/model combination.".format( realization_pk) return q_error(request, msg) # no need to generate any forms or formsets; I do that all via the load-on-demand paradigm # work out the various paths, # so that ng can reload things as needed # (notice these are slightly different than in "q_edit_new" above view_url = request.path view_url_sections = [section for section in view_url.split('/') if section] view_url_dirname = '/'.join(view_url_sections[:-1]) api_url = reverse("realization-detail", kwargs={"pk": model_realization.pk}) api_url_sections = [section for section in api_url.split('/') if section] api_url_dirname = '/'.join(api_url_sections[:-1]) # gather all the extra information required by the template _dict = { "session_key": session_key, "view_url_dirname": "/{0}/".format(view_url_dirname), "api_url_dirname": "/{0}/".format(api_url_dirname), "project": project, "ontology": ontology, "proxy": model_proxy, "realization": model_realization, "customization": model_customization, "read_only": "true", } return render_to_response('questionnaire/q_view.html', _dict, context_instance=context)
def q_edit_new(request, project_name=None, ontology_key=None, document_type=None): # save any request parameters... # (in case of redirection) context = add_parameters_to_context(request) # check the arguments... validity, project, ontology, model_proxy, model_customization, msg = validate_view_arguments( project_name=project_name, ontology_key=ontology_key, document_type=document_type ) if not validity: return q_error(request, msg) # check authentication... # (not using "@login_required" b/c some projects ignore authentication) current_user = request.user if project.authenticated: if not current_user.is_authenticated(): next_page = "/login/?next=%s" % request.path return HttpResponseRedirect(next_page) if not is_user_of(current_user, project): next_page = "/%s/" % project_name msg = "You have tried to view a restricted resource for this project. Please consider joining." messages.add_message(request, messages.WARNING, msg) return HttpResponseRedirect(next_page) # get (or set) realization objects from the cache... session_key = get_key_from_request(request) # # no need to cache customizations; I access them as needed during form creation # # cached_customizations_key = "{0}_customizations".format(session_key) # # model_customization = get_or_create_cached_object(request.session, cached_customizations_key, # # get_existing_customizations, # # **{ # # "project": project, # # "ontology": ontology, # # "model_proxy": model_proxy, # # "customization_id": customization.id, # # } # # ) cached_realizations_key = "{0}_realizations".format(session_key) model_realization = get_or_create_cached_object(request.session, cached_realizations_key, get_new_realizations, **{ "project": project, "ontology": ontology, "model_proxy": model_proxy, "key": model_proxy.name, "customization": model_customization, } ) if current_user.is_authenticated(): set_owner(model_realization, evaluate_lazy_object(current_user)) # TODO: THIS IS A ONE-OFF TO GET ME THROUGH THE MEDIUM-TERM # TODO: IN THE LONG-TERM I OUGHT TO FIGURE OUT HOW TO AUTOMATICALLY WORK OUT HOW/WHEN TO SET "is_root" # TODO: (MOST LIKELY IT SHOULD BE IN "Q.questionnaire.models.models_realizations.QModel#reset") model_realization.is_root = True # no need to generate any forms or formsets; I do that all via the load-on-demand paradigm # work out the various paths, # so that ng can reload things as needed view_url = request.path view_url_sections = [section for section in view_url.split('/') if section] view_url_dirname = '/'.join(view_url_sections[:]) api_url = reverse("realization-list", kwargs={}) api_url_sections = [section for section in api_url.split('/') if section] api_url_dirname = '/'.join(api_url_sections[:]) # gather all the extra information required by the template _dict = { "session_key": session_key, "view_url_dirname": "/{0}/".format(view_url_dirname), "api_url_dirname": "/{0}/".format(api_url_dirname), "project": project, "ontology": ontology, "proxy": model_proxy, "realization": model_realization, "customization": model_customization, "read_only": "false", } return render_to_response('questionnaire/q_edit.html', _dict, context_instance=context)