Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FieldError when sorting a column which defines a function as the 'data' attribute #86

Open
matthewhegarty opened this issue Jun 10, 2020 · 5 comments
Labels
Documentation help wanted Extra attention is needed

Comments

@matthewhegarty
Copy link
Collaborator

matthewhegarty commented Jun 10, 2020

My Javascript defines a function for the columns.data attribute:

  $('#player-table').DataTable({
      "serverSide": true,
      "ajax": {
          "url": "{% url "api:player-list" %}?format=datatables",
      },
      "columns": [
        "data": function ( row, type, val, meta ) {
            return row.my_val;
        }
     ]   
})

This works fine when displaying the table - the values are rendered correctly. However, when sorting the column, this sends a request which triggers a crash with FieldError:

Exception Type: FieldError at /api/player/
Exception Value: Cannot resolve keyword 'function' into field. 

Sure enough, the request sends data=function, and I thought that this was the source of the issue, but this actually gets sent with successful requests as well.

Crashes:

http://localhost:8000/api/player/?format=datatables&draw=6&columns%5B0%5D%5Bdata%5D=uid&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=function&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=false&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=netreturn_total_90_day&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=false&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=deposit_total_90_day&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=false&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=withdrawal_total_90_day&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=false&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=id&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=false&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=1&order%5B0%5D%5Bdir%5D=desc&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&range=28&_=1591817768441

Returns OK:

http://localhost:8000/api/player/?format=datatables&draw=1&columns%5B0%5D%5Bdata%5D=uid&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=function&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=false&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=netreturn_total_90_day&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=false&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=deposit_total_90_day&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=false&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=withdrawal_total_90_day&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=false&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=id&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=false&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&range=28&_=1591817934274

Stack trace:

drfdt_st1.txt

Workaround

Very very nasty hack is to declare an attribute on the model in question called function. This prevents the crash, but sorting still does not work.

@matthewhegarty
Copy link
Collaborator Author

I've reproduced the issue here.

To reproduce:

  • clone the branch
  • Start the example app
  • Click on the 'Album name' 'sort' icon (Full example)

@sandeepbalagopal09
Copy link

sandeepbalagopal09 commented Aug 28, 2020

I am getting the error when search is done. custom functions are not working.

@sandeepbalagopal09
Copy link

hey @matthewhegarty take a look at #83 . set orderable: false, searchable: false,

https://datatables.net/reference/option/columns.orderable

@izimobil
Copy link
Owner

This should be documented, as well as other cases where setting orderable: false, searchable: false is necessary to prevent a server side error. PR anyone ? @matthewhegarty @sandeepbalagopal09

@izimobil izimobil added Documentation help wanted Extra attention is needed labels Apr 21, 2021
@lampslave
Copy link

@izimobil why don't you want to use name as alternative to data in this case?

  $('#player-table').DataTable({
      "serverSide": true,
      "ajax": {
          "url": "{% url "api:player-list" %}?format=datatables",
      },
      "columns": [
        "data": function ( row, type, val, meta ) {
            return row.my_val;
        },
        "name": "my_val"
     ]   
})

Just modify that lines

col = 'columns[%d][%s]'
data = get_param(request, col % (i, 'data'))
if data == "": # null or empty string on datatables (JS) side
fields.append({'searchable': False, 'orderable': False})
i += 1
continue
# break out only when there are no more fields to get.
if data is None:
break
name = get_param(request, col % (i, 'name'))
if not name:
name = data

like this

col = 'columns[%d][%s]'
data = get_param(request, col % (i, 'data'))
name = get_param(request, col % (i, 'name'))
if (data == 'function') and name:
    data = name

(not a full replacement, just for illustration).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

4 participants