Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)