2017-01-11 2 views
1

Использование DataTables плагин jQuery с serverSide = true (пример здесь маленький, но в конечном итоге мы хотим обрабатывать большое количество записей). При первоначальном запросе (загрузка первой страницы) все работает нормально. DataTable отлично смотрится и содержит ожидаемые данные.DataTables (serverSide) OK при первом запросе, с ошибкой «Объект объекта»] при запросе при поиске или переупорядочении

Запрос информации

Request method = GET 
Request args = ImmutableMultiDict([('draw', u'1'), ('columns[0][data]', u'client_user_id'), ('columns[1][name]', u''), ('columns[5][searchable]', u'true'), ('columns[5][name]', u''), ('columns[4][search][regex]', u'false'), ('columns[1][orderable]', u'true'), ('columns[4][orderable]', u'true'), ('columns[5][orderable]', u'true'), ('columns[2][orderable]', u'true'), ('columns[4][name]', u''), ('order[0][dir]', u'asc'), ('columns[1][search][regex]', u'false'), ('columns[3][name]', u''), ('columns[0][search][value]', u''), ('columns[2][searchable]', u'true'), ('columns[3][search][regex]', u'false'), ('extra_search', u'test'), ('columns[0][search][regex]', u'false'), ('columns[5][data]', u'last_login'), ('start', u'0'), ('columns[4][searchable]', u'true'), ('columns[0][searchable]', u'true'), ('columns[5][search][value]', u''), ('columns[3][searchable]', u'true'), ('columns[2][search][value]', u''), ('columns[2][search][regex]', u'false'), ('columns[1][data]', u'status'), ('columns[1][searchable]', u'true'), ('columns[5][search][regex]', u'false'), ('columns[0][orderable]', u'true'), ('columns[4][data]', u'client_id'), ('columns[0][name]', u''), ('columns[2][data]', u'lastname'), ('columns[3][data]', u'email_address'), ('search[value]', u''), ('columns[3][orderable]', u'true'), ('_', u'1484145221101'), ('columns[4][search][value]', u''), ('search[regex]', u'false'), ('columns[1][search][value]', u''), ('order[0][column]', u'0'), ('columns[2][name]', u''), ('length', u'10'), ('columns[3][search][value]', u'')]) 
127.0.0.1 - - [11/Jan/2017 09:33:41] "GET /client/rou/ajax/mwe?draw=1&columns%5B0%5D%5Bdata%5D=client_user_id&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=true&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=status&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=true&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=lastname&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=true&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=email_address&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=true&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=client_id&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=true&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=last_login&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=true&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&extra_search=test&_=1484145221101 HTTP/1.1" 200 - 

... и данные возвращаются с сервера. Однако любое взаимодействие с DataTable (например, щелкнув заголовок столбца для сортировки результата, или введите в поле поиска) и последующие запросы AJAX выглядеть следующим образом:

Запрос информации при попытке поиска или сортировки

Request method = GET 
Request args = ImmutableMultiDict([('[object Object]', u''), ('_', u'1484145221102')]) 
127.0.0.1 - - [11/Jan/2017 09:33:46] "GET /client/rou/ajax/mwe?[object%20Object]&_=1484145221102 HTTP/1.1" 200 - 

Почему в первом случае мы получаем все параметры OK, а во втором случае получаем [Object object]? Какие изменения необходимы, чтобы DataTables выдавал действительные запросы?

Python (с использованием колба)

@blueprint.route('/rou/ajax/mwe', methods=("GET", "POST")) 
def b_ajax_mwe(): 

    error = False 
    error_text = None 
    data = [] 

    print("Request method = {}".format(request.method)) 
    print("Request args = {}".format(request.args)) 
    draw = request.args.get('draw') or 1 

    try: 
     # Yes, I know this always returns same result... for now 
     # once we have request from DataTable that's not "[Object object]" 
     # we will modify to return data based on request 
     query = ClientUser.query \ 
      .filter(ClientUser.client_id == 2) \ 
      .limit(10) \ 
      .all() 

     data = [{'client_user_id': cu.client_user_id, 
       'status': cu.status, 
       'email_address': cu.email_address, 
       'lastname': cu.lastname, 
       'client_id': cu.client_id, 
       'last_login': cu.last_login} for cu in query] 

    except Exception, err: 
     error = True 
     error_text = str(err) 

    rows = ClientUser.query.count() 

    result = {'draw': draw, 
       'recordsTotal': rows, 
       'recordsFiltered': len(data), 
       'data': data} 

    if error: 
     result['error'] = error_text 

    return jsonify(result) 

HTML (в голове)

<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/bs/dt-1.10.13/datatables.min.css"/> 

HTML (в теле)

<table class="table display" id="mwe_table"> 
    <thead> 
     <tr> 
      <th>User ID</th> 
      <th>Status</th> 
      <th>Last name</th> 
      <th>Email</th> 
      <th>Client ID</th> 
      <th>Last login</th> 
     </tr> 
    </thead> 
    <tbody></tbody> 
</table> 

...

<script type="text/javascript" src="https://cdn.datatables.net/v/bs/dt-1.10.13/datatables.min.js"></script> 

(JQuery 1,11 загружен до вещи из DataTables CDN, выше)

JavaScript

$(document).ready(function() { 

    $('#mwe_table').DataTable({ 
     processing: true, 
     serverSide: true, 
     ajax: { 
      method: 'GET', 
      url: '/client/rou/ajax/mwe', 
     }, 
     "columns": [ 
      { "data": "client_user_id" }, 
      { "data": "status" }, 
      { "data": "lastname" }, 
      { "data": "email_address" }, 
      { "data": "client_id" }, 
      { "data": "last_login" } 
     ] 
    }); 
}); 

Нет ошибок представлены в консоли JavaScript.

+0

Это, вероятно, не решит вашу проблему, но 'recordTotal' и' recordsFiltered', вероятно, должны быть одинаковыми в этом случае. В документации «recordsFiltered» должно быть «общее количество записей после применения фильтрации», а не только количество записей, возвращаемых для этой страницы данных. – dana

+0

Понял. Благодарю. – PartialOrder

ответ

1

Мне не удалось воспроизвести, используя указанные параметры, но думаю, что у меня может быть обходной путь. Вы можете явно указать DataTables, как сериализовать данные запроса.

Например:

$(document).ready(function() { 

    $('#mwe_table').DataTable({ 
     processing: true, 
     serverSide: true, 
     ajax: { 
      url: '/client/rou/ajax/mwe', 
      data: function (d) { 
       console.log(d); // display all properties to console 
       return jQuery.param({ 
        start: d.start, 
        length: d.length, 
        orderColumn: d.order[0].column, 
        orderDir: d.order[0].dir, 
        draw: d.draw 
       }); 
      } 
     }, 
     "columns": [ 
      { "data": "client_user_id" }, 
      { "data": "status" }, 
      { "data": "lastname" }, 
      { "data": "email_address" }, 
      { "data": "client_id" }, 
      { "data": "last_login" } 
     ] 
    }); 
}); 

Обратите внимание, что я выборочно отправки некоторых параметров с помощью сериализации объекта JavaScript в application/x-www-form-urlencodedjQuery.param() использованием. Для простоты объект JavaScript имеет только простые свойства и не имеет вложенных объектов или массивов. Вызов jQuery.param(), вероятно, не нужен, но я оставил его в явном виде.