def action_index(request): """ Render the list of actions attached to a workflow. :param request: Request object :return: HTTP response with the table. """ # Get the appropriate workflow object workflow = get_workflow(request) if not workflow: return redirect('workflow:index') # Get the actions actions = Action.objects.filter( workflow__id=workflow.id) # Context to render the template context = {'has_table': ops.workflow_has_table(workflow)} # Build the table only if there is anything to show (prevent empty table) qset = [] for action in actions: qset.append({'id': action.id, 'name': action.name, 'description_text': action.description_text, 'is_out': action.is_out, 'is_correct': action.is_correct, 'modified': action.modified, 'serve_enabled': action.serve_enabled}) context['table'] = ActionTable(qset, orderable=False) return render(request, 'action/index.html', context)
def edit_action_out(request, pk): """ View to handle the AJAX form to edit an action (editor, conditions, filters, etc). :param request: Request object :param pk: Action PK :return: JSON response """ # Try to get the workflow first workflow = get_workflow(request) if not workflow: return redirect('workflow:index') # Get the action and create the form try: action = Action.objects.filter( Q(workflow__user=request.user) | Q(workflow__shared=request.user)).distinct().get(pk=pk) except ObjectDoesNotExist: return redirect('action:index') # Create the form form = EditActionOutForm(request.POST or None, instance=action) # See if the action has a filter or not try: filter_condition = Condition.objects.get( action=action, is_filter=True ) except Condition.DoesNotExist: filter_condition = None except Condition.MultipleObjectsReturned: return render(request, 'error.html', {'message': 'Malfunction detected when retrieving filter ' '(action: {0})'.format(action.id)}) # Conditions to show in the page as well. conditions = Condition.objects.filter( action=action, is_filter=False ).order_by('created').values('id', 'name') # Boolean to find out if there is a table attached to this workflow has_data = ops.workflow_has_table(action.workflow) # Get the total number of rows in DF and those selected by filter. total_rows = workflow.nrows if filter_condition: action.n_selected_rows = \ pandas_db.num_rows(action.workflow.id, filter_condition.formula) # Context to render the form context = {'filter_condition': filter_condition, 'action': action, 'conditions': conditions, 'query_builder_ops': workflow.get_query_builder_ops_as_str(), 'attribute_names': [x for x in workflow.attributes.keys()], 'column_names': workflow.get_column_names(), 'selected_rows': action.n_selected_rows, 'has_data': has_data, 'total_rows': total_rows, 'form': form, 'vis_scripts': PlotlyHandler.get_engine_scripts() } # Processing the request after receiving the text from the editor if request.method == 'POST': # Get the next step next_step = request.POST['Submit'] if form.is_valid(): content = form.cleaned_data.get('content', None) # TODO: Can we detect unused vars only for this invocation? # Render the content as a template and catch potential problems. # This seems to be only possible if dealing directly with Jinja2 # instead of Django. try: render_template(content, {}, action) except Exception as e: # Pass the django exception to the form (fingers crossed) form.add_error(None, e.message) return render(request, 'action/edit_out.html', context) # Log the event logs.ops.put(request.user, 'action_update', action.workflow, {'id': action.id, 'name': action.name, 'workflow_id': workflow.id, 'workflow_name': workflow.name, 'content': content}) # Text is good. Update the content of the action action.content = content action.save() # Closing if next_step == 'Save-and-close': return redirect('action:index') # Return the same form in the same page return render(request, 'action/edit_out.html', context=context)
def edit_action_in(request, pk): """ View to handle the AJAX form to edit an action in (filter + columns). :param request: Request object :param pk: Action PK :return: HTTP response """ # Check if the workflow is locked workflow = get_workflow(request) if not workflow: return redirect('workflow:index') if workflow.nrows == 0: messages.error(request, 'Workflow has no data. ' 'Go to Dataops to upload data.') return redirect(reverse('action:index')) # Get the action and the columns try: action = Action.objects.filter( Q(workflow__user=request.user) | Q(workflow__shared=request.user) ).distinct().prefetch_related('columns').get(pk=pk) except ObjectDoesNotExist: return redirect('action:index') if action.is_out: # Trying to edit an incorrect action. Redirect to index return redirect('action:index') # See if the action has a filter or not try: filter_condition = Condition.objects.get( action=action, is_filter=True ) except Condition.DoesNotExist: filter_condition = None except Condition.MultipleObjectsReturned: return render(request, 'error.html', {'message': 'Malfunction detected when retrieving filter ' '(action: {0})'.format(action.id)}) # Get the number of rows in DF selected by filter. if filter_condition: filter_condition.n_rows_selected = \ pandas_db.num_rows(action.workflow.id, filter_condition.formula) filter_condition.save() # Column names suitable to insert columns_selected = action.columns.filter(is_key=False).order_by('position') columns_to_insert = [c for c in workflow.columns.all() if not c.is_key and c not in columns_selected] # Has key column and has no-key column has_no_key = action.columns.filter(is_key=False).exists() has_empty_description = columns_selected.filter( description_text='' ).exists() # Create the context info. ctx = {'action': action, 'filter_condition': filter_condition, 'selected_rows': filter_condition.n_rows_selected if filter_condition else -1, 'total_rows': workflow.nrows, 'query_builder_ops': workflow.get_query_builder_ops_as_str(), 'has_data': ops.workflow_has_table(action.workflow), 'key_selected': action.columns.filter(is_key=True).first(), 'columns_to_insert': columns_to_insert, 'column_selected_table': ColumnSelectedTable( columns_selected.values('id', 'name', 'description_text'), orderable=False, extra_columns=[ ('operations', OperationsColumn( verbose_name='Ops', template_file=ColumnSelectedTable.ops_template, template_context=lambda record: {'id': record['id'], 'aid': action.id}) )] ), 'has_no_key': has_no_key, 'has_empty_description': has_empty_description} return render(request, 'action/edit_in.html', ctx)