def column_delete( request: HttpRequest, pk: int, workflow: Optional[models.Workflow] = None, column: Optional[models.Column] = None, ) -> JsonResponse: """Delete a column in the table attached to a workflow. :param request: HTTP request :param pk: ID of the column to delete. :param workflow: Workflow being processed :param column: Column to delete (set by the decorator) :return: Render the delete column form """ # Get the workflow element # If the columns is unique and it is the only one, we cannot allow # the operation unique_column = workflow.get_column_unique() if column.is_key and len([col for col in unique_column if col]) == 1: # This is the only key column messages.error(request, _('You cannot delete the only key column')) return JsonResponse({'html_redirect': reverse('workflow:detail')}) # Get the name of the column to delete context = {'pk': pk, 'cname': column.name} # Get the conditions/actions attached to this workflow cond_to_delete = [ col for col in models.Condition.objects.filter(action__workflow=workflow) if evaluation.has_variable(col.formula, column.name) ] # Put it in the context because it is shown to the user before confirming # the deletion context['cond_to_delete'] = cond_to_delete if request.method == 'POST': services.delete_column(request.user, workflow, column, cond_to_delete) # There are various points of return from_url = request.META['HTTP_REFERER'] if from_url.endswith(reverse('table:display')): return JsonResponse({'html_redirect': reverse('table:display')}) return JsonResponse({'html_redirect': reverse('workflow:detail')}) return JsonResponse({ 'html_form': render_to_string('workflow/includes/partial_column_delete.html', context, request=request), })
def test_table_pandas_merge_to_outer_NaN(self): # Get the only workflow in the fixture workflow = models.Workflow.objects.all()[0] age = workflow.columns.filter(name='age')[0] age.is_key = False age.save() email = workflow.columns.filter(name='email')[0] email.is_key = False email.save() # Drop the column with booleans because the data type is lost delete_column(self.user, workflow, workflow.columns.get(name='registered')) # Transform new table into string r_df = pd.DataFrame(self.src_df2) # Load the df from the db dframe = pandas.load_table(workflow.get_data_frame_table_name()) new_df = pd.merge(dframe, r_df, how="outer", left_on="sid", right_on="sid") # Get the data through the API self.client.put(reverse('table:api_pmerge', kwargs={'wid': workflow.id}), { "src_df": serializers.df_to_string(r_df), "how": "outer", "left_on": "sid", "right_on": "sid" }, format='json') # Get the new workflow workflow = models.Workflow.objects.all()[0] # Result should have three rows as the initial DF self.assertEqual(workflow.nrows, 4) self.assertEqual(workflow.ncols, 8) # Load the df from the db dframe = pandas.load_table(workflow.get_data_frame_table_name()) # Compare both elements and check wf df consistency self.compare_tables(dframe, new_df)
def test_create_random_column_datetime_form(self): """Create a random number column with no values""" # Get the workflow first self.workflow = models.Workflow.objects.all().first() # Column name and current number of them cname = 'random_column' ncols = self.workflow.ncols # JSON POST request for column creation with incorrect string value resp = self.get_response('workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'datetime', 'raw_categories': 'bogus', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNone(new_column) # JSON POST request for column creation with a single integer resp = self.get_response('workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'datetime', 'raw_categories': '2020-09-11 12:04:43+0930', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNone(new_column) # JSON POST request for column creation with a multiple strings dtimes = [ parse_datetime('2020-09-11 12:04:43+0930'), parse_datetime('2020-09-12 12:04:43+0930') ] resp = self.get_response( 'workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'datetime', 'raw_categories': '2020-09-11 12:04:43+0930, 2020-09-12 12:04:43+0930', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' not in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols + 1) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNotNone(new_column) self.assertEqual(new_column.name, cname) self.assertEqual(new_column.data_type, 'datetime') data_frame = pandas.load_table( self.workflow.get_data_frame_table_name()) self.assertTrue(all(element in dtimes for element in data_frame[cname])) # Delete the column services.delete_column(self.workflow.user, self.workflow, new_column)
def test_create_random_column_boolean_form(self): """Create a random string column""" # Get the workflow first self.workflow = models.Workflow.objects.all().first() # Column name and current number of them cname = 'random_column' ncols = self.workflow.ncols # JSON POST request for column creation with string value resp = self.get_response('workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'boolean', 'raw_categories': 'bogus', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNone(new_column) # JSON POST request for column creation with string value resp = self.get_response('workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'boolean', 'raw_categories': 'one, two', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' not in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols + 1) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNotNone(new_column) self.assertEqual(new_column.name, cname) self.assertEqual(new_column.data_type, 'boolean') data_frame = pandas.load_table( self.workflow.get_data_frame_table_name()) self.assertTrue(all(not element for element in data_frame[cname])) # Delete the column services.delete_column(self.workflow.user, self.workflow, new_column) # JSON POST request for column creation with a string list resp = self.get_response('workflow:random_column_add', method='POST', req_params={ 'name': cname, 'data_type': 'boolean', 'raw_categories': 'True, False', 'position': 0 }, is_ajax=True) resp_content = json.loads(resp.content) self.assertTrue('html_form' not in resp_content) self.assertTrue(status.is_success(resp.status_code)) self.workflow.refresh_from_db() self.assertEqual(self.workflow.ncols, ncols + 1) new_column = self.workflow.columns.filter(name=cname).first() self.assertIsNotNone(new_column) self.assertEqual(new_column.name, cname) self.assertEqual(new_column.data_type, 'boolean') data_frame = pandas.load_table( self.workflow.get_data_frame_table_name()) self.assertTrue( all(element in [True, False] for element in data_frame[cname]))