示例#1
0
    def post(self, request, *args, **kwargs):
        """
        Edits a Project via "diffs" from a configuration file ala execute_project_config_diff(). Runs in the calling
        thread and therefore blocks. POST form fields:
        - request.data (required) must have a 'project_config' field containing a dict valid for
            execute_project_config_diff(). NB: this is different from other API args in this file in that it takes all
            required information as data, whereas others take their main data as a file in request.FILES, plus some
            additional data in request.data.
        """
        project = self.get_object()
        if not is_user_ok_edit_project(request.user, project):  # only the project owner can edit the project
            return HttpResponseForbidden()
        elif 'project_config' not in request.data:
            return JsonResponse({'error': "No 'project_config' data."}, status=status.HTTP_400_BAD_REQUEST)

        try:
            current_config_dict = config_dict_from_project(project, request)
            new_config_dict = request.data['project_config']
            changes = project_config_diff(current_config_dict, new_config_dict)
            # database_changes = database_changes_for_project_config_diff(project, changes)
            logger.debug(f"ProjectDetail.post(): executing project config diff... changes={changes}")
            execute_project_config_diff(project, changes)
            logger.debug(f"ProjectDetail.post(): done")
            project_serializer = ProjectSerializer(project, context={'request': request})
            return JsonResponse(project_serializer.data)
        except Exception as ex:
            return JsonResponse({'error': str(ex)}, status=status.HTTP_400_BAD_REQUEST)
    def test_diff_from_file(self):
        _, _, po_user, _, _, _, _, _ = get_or_create_super_po_mo_users(
            is_create_super=True)
        project, _, _, _ = _make_docs_project(po_user)
        out_config_dict = config_dict_from_project(
            project,
            APIRequestFactory().request())

        # this json file makes the same changes as _make_some_changes():
        with open(
                Path('forecast_app/tests/project_diff/docs-project-edited.json'
                     )) as fp:
            edited_config_dict = json.load(fp)
        changes = project_config_diff(out_config_dict, edited_config_dict)

        # # print a little report
        # print(f"* Analyzed {len(changes)} changes. Results:")
        # for change, num_points, num_named, num_bins, num_samples, num_quantiles, num_truth in \
        #         database_changes_for_project_config_diff(project, changes):
        #     print(f"- {change.change_type.name} on {change.object_type.name} {change.object_pk!r} will delete:\n"
        #           f"  = {num_points} point predictions\n"
        #           f"  = {num_named} named predictions\n"
        #           f"  = {num_bins} bin predictions\n"
        #           f"  = {num_samples} samples\n"
        #           f"  = {num_quantiles} quantiles\n"
        #           f"  = {num_truth} truth rows")

        # same tests as test_execute_project_config_diff():
        execute_project_config_diff(project, changes)
        self._do_make_some_changes_tests(project)
    def test_execute_project_config_diff(self):
        _, _, po_user, _, _, _, _, _ = get_or_create_super_po_mo_users(
            is_create_super=True)
        project, _, _, _ = _make_docs_project(po_user)

        # make some changes
        out_config_dict = config_dict_from_project(
            project,
            APIRequestFactory().request())
        edit_config_dict = copy.deepcopy(out_config_dict)
        _make_some_changes(edit_config_dict)

        changes = project_config_diff(out_config_dict, edit_config_dict)
        execute_project_config_diff(project, changes)
        self._do_make_some_changes_tests(project)
    def test_execute_project_config_diff(self):
        _, _, po_user, _, _, _, _, _ = get_or_create_super_po_mo_users(
            is_create_super=True)
        project, _, _, _ = _make_docs_project(po_user)
        _update_scores_for_all_projects()

        # make some changes
        # note: using APIRequestFactory was the only way I could find to pass a request object. o/w you get:
        #   AssertionError: `HyperlinkedIdentityField` requires the request in the serializer context.
        out_config_dict = config_dict_from_project(
            project,
            APIRequestFactory().request())
        edit_config_dict = copy.deepcopy(out_config_dict)
        _make_some_changes(edit_config_dict)

        changes = project_config_diff(out_config_dict, edit_config_dict)
        execute_project_config_diff(project, changes)
        self._do_make_some_changes_tests(project)