def render_table_display_data(request, workflow, columns, formula, view_id=None): """ Render the appropriate subset of the data table. Use the search string provided in the UI + the filter (if applicable) taken from a view. :param request: AJAX request :param workflow: workflow object :param columns: Subset of columns to consider :param formula: Expression to filter rows :param view_id: ID of the view restricting the display (if any) :return: """ # Check that the GET parameter are correctly given try: draw = int(request.POST.get('draw', None)) start = int(request.POST.get('start', None)) length = int(request.POST.get('length', None)) order_col_name = request.POST.get('order[0][column]', None) order_dir = request.POST.get('order[0][dir]', 'asc') except ValueError: return JsonResponse( {'error': _('Incorrect request. Unable to process')}) # Get the column information from the request and the rest of values. search_value = request.POST.get('search[value]', None) # Get columns and names column_names = [x.name for x in columns] # See if an order has been given. if order_col_name: # The first column is ops order_col_name = column_names[int(order_col_name) - 1] # Find the first key column key_name, key_idx = next( ((c.name, idx) for idx, c in enumerate(columns) if c.is_key), None) # Get the filters to apply when fetching the query set cv_tuples = [] if search_value: cv_tuples.extend([(c.name, search_value, c.data_type) for c in columns]) qs = pandas_db.search_table_rows(workflow.id, cv_tuples, True, order_col_name, order_dir == 'asc', column_names, formula) # Post processing + adding operation columns and performing the search final_qs = [] items = 0 # For counting the number of elements in the result for row in qs[start:start + length]: items += 1 if view_id: stat_url = reverse('table:stat_row_view', kwargs={'pk': view_id}) else: stat_url = reverse('table:stat_row') ops_string = render_to_string( 'table/includes/partial_table_ops.html', { 'stat_url': stat_url + '?key={0}&val={1}'.format(key_name, row[key_idx]), 'edit_url': reverse('dataops:rowupdate') + '?update_key={0}&update_val={1}'.format( key_name, row[key_idx]), 'delete_key': '?key={0}&value={1}'.format(key_name, row[key_idx]), 'view_id': view_id }) # Element to add to the final queryset new_element = [ops_string] + list(row) # Tweak the date time format new_element = map( lambda x: x.strftime('%Y-%m-%d %H:%M:%S %z') if isinstance(x, datetime) else x, new_element) # Create the list of elements to display and add it ot the final QS final_qs.append(new_element) if items == length: # We reached the number or requested elements, abandon. break # Result to return as Ajax response data = { 'draw': draw, 'recordsTotal': workflow.nrows, 'recordsFiltered': len(qs), 'data': final_qs } return JsonResponse(data)
def run_ss(request, pk): """ Serve the AJAX requests to show the elements in the table that satisfy the filter and between the given limits. :param request: :param pk: action id being run :return: """ workflow = get_workflow(request) if not workflow: return JsonResponse({'error': 'Incorrect request. Unable to process'}) # If there is not DF, go to workflow details. if not ops.workflow_id_has_table(workflow.id): return JsonResponse({'error': 'There is no data in the table'}) # Get the action 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') # Check that the GET parameter are correctly given try: draw = int(request.POST.get('draw', None)) start = int(request.POST.get('start', None)) length = int(request.POST.get('length', None)) order_col = request.POST.get('order[0][column]', None) order_dir = request.POST.get('order[0][dir]', 'asc') except ValueError: return JsonResponse({'error': 'Incorrect request. Unable to process'}) # Get the column information from the request and the rest of values. search_value = request.POST.get('search[value]', None) # Get columns columns = action.columns.all() column_names = [x.name for x in columns] # See if an order column has been given. if order_col: order_col = columns[int(order_col)] # Get the search pairs of field, value cv_tuples = [] if search_value: cv_tuples = [(c.name, search_value, c.data_type) for c in columns] # Get the query set (including the filter in the action) qs = pandas_db.search_table_rows( workflow.id, cv_tuples, True, order_col.name, order_dir == 'asc', column_names, # Column names in the action action.filter # Filter in the action ) # Post processing + adding operations final_qs = [] items = 0 for row in qs[start:start + length]: items += 1 # Render the first element (the key) as the link to the page to update # the content. dst_url = reverse('action:run_row', kwargs={'pk': action.id}) url_parts = list(urlparse.urlparse(dst_url)) query = dict(urlparse.parse_qs(url_parts[4])) query.update({'uatn': column_names[0], 'uatv': row[0]}) url_parts[4] = urlencode(query) link_item = '<a href="{0}">{1}</a>'.format( urlparse.urlunparse(url_parts), row[0] ) # Add the row for rendering final_qs.append([link_item] + list(row)[1:]) if items == length: # We reached the number or requested elements, abandon loop break data = { 'draw': draw, 'recordsTotal': workflow.nrows, 'recordsFiltered': len(qs), 'data': final_qs } return JsonResponse(data)