GithubHelp home page GithubHelp logo

izimobil / django-rest-framework-datatables Goto Github PK

View Code? Open in Web Editor NEW
385.0 385.0 87.0 345 KB

Seamless integration between Django REST framework and Datatables.

Home Page: http://django-rest-framework-datatables.readthedocs.io/en/latest/

License: MIT License

Python 90.28% HTML 7.15% CSS 2.22% Shell 0.36%
api datagrid datatable-serverside datatables django django-rest-framework drf

django-rest-framework-datatables's People

Contributors

atnartur avatar benedicthsieh avatar bnjblm avatar browniebroke avatar bryan-brancotte avatar carlosborroto avatar computerquest avatar cristopherh95 avatar felixxm avatar invisi avatar irtazaakram avatar izimobil avatar jerzyk avatar johnazedo avatar kluchrj avatar kpavlovsky avatar matthewhegarty avatar maysu1914 avatar moisesgsalas avatar morenoh149 avatar neighlyd avatar parander avatar samatix avatar sworleys avatar taupan avatar vanschelven avatar viseshrp avatar youshouldtellmemore avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-rest-framework-datatables's Issues

Dealing with nested relationships

Hello,

I apologize if this isn't the right place to ask this question, but I am having a rough time trying to get this package working with nested relationships. I have tried using DRFs built in solution, DRF-Flex-Fields, and Dynamic Rest. None of these options seem to be able to expand my sub-serializers and apply the DRF-Datatables formatting appropriately.

Instead, what is happening is that the nested relationships are being stripped away and only the first layer is being presented within the data:[...] layer that is fed to the datatable.

URL too long

Heya, first off thanks a lot for this module as it is super simple to implement and very effective.

I am having this issue where the ajax-url becomes longer than 2000characters and therefore stops functioning and I assume I am doing something wrong.

This is the url i get:
/models/result_overview/?format=datatables&Lot=&MatNo=&Product=&Comment=&Tester=&Result__testDate_min=&Result__testDate_max=&TestEquipment=7500%2F5%3A%20Zwick&TestInstruction=&Result__Tag__name=&draw=9&columns%5B0%5D%5Bdata%5D=id&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=true&columns%5B0%5D%5Borderable%5D=false&columns%5B0%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B0%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B1%5D%5Bdata%5D=MatNo&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=true&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=Lot&columns%5B2%5D%5Bname%5D=&columns%5B2%5D%5Bsearchable%5D=true&columns%5B2%5D%5Borderable%5D=false&columns%5B2%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B2%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B3%5D%5Bdata%5D=SerialID&columns%5B3%5D%5Bname%5D=&columns%5B3%5D%5Bsearchable%5D=true&columns%5B3%5D%5Borderable%5D=false&columns%5B3%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B3%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B4%5D%5Bdata%5D=Tester&columns%5B4%5D%5Bname%5D=&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B5%5D%5Bdata%5D=Result&columns%5B5%5D%5Bname%5D=&columns%5B5%5D%5Bsearchable%5D=true&columns%5B5%5D%5Borderable%5D=false&columns%5B5%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B5%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B6%5D%5Bdata%5D=TestEquipment&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=false&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=TestInstruction&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=true&columns%5B7%5D%5Borderable%5D=false&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&start=0&length=10&search%5Bvalue%5D=&search%5Bregex%5D=false&_=1581405486114

This is the same URL decoded:
/models/result_overview/?format=datatables&Lot=&MatNo=&Product=&Comment=&Tester=&Result__testDate_min=&Result__testDate_max=&TestEquipment=7500/5: Zwick&TestInstruction=&Result__Tag__name=&draw=9&columns[0][data]=id&columns[0][name]=&columns[0][searchable]=true&columns[0][orderable]=false&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=MatNo&columns[1][name]=&columns[1][searchable]=true&columns[1][orderable]=false&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=Lot&columns[2][name]=&columns[2][searchable]=true&columns[2][orderable]=false&columns[2][search][value]=&columns[2][search][regex]=false&columns[3][data]=SerialID&columns[3][name]=&columns[3][searchable]=true&columns[3][orderable]=false&columns[3][search][value]=&columns[3][search][regex]=false&columns[4][data]=Tester&columns[4][name]=&columns[4][searchable]=true&columns[4][orderable]=false&columns[4][search][value]=&columns[4][search][regex]=false&columns[5][data]=Result&columns[5][name]=&columns[5][searchable]=true&columns[5][orderable]=false&columns[5][search][value]=&columns[5][search][regex]=false&columns[6][data]=TestEquipment&columns[6][name]=&columns[6][searchable]=true&columns[6][orderable]=false&columns[6][search][value]=&columns[6][search][regex]=false&columns[7][data]=TestInstruction&columns[7][name]=&columns[7][searchable]=true&columns[7][orderable]=false&columns[7][search][value]=&columns[7][search][regex]=false&start=0&length=10&search[value]=&search[regex]=false&_=1581405486114

Applying distinct sometimes results in errors

I'm using postgresql as my database.

The example works perfectly as-is. Additionally, if I change

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all().order_by('rank')
    serializer_class = AlbumSerializer

to

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all().order_by('rank').distinct('rank')
    serializer_class = AlbumSerializer

or

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all().order_by('id').distinct('id')
    serializer_class = AlbumSerializer

everything works as expected. I get object instances with distinct rank or id.

But, if instead I set distinct to 'year', which just like rank is a PositiveIntegerField in the model:

class AlbumViewSet(viewsets.ModelViewSet):
    queryset = Album.objects.all().order_by('year').distinct('year')
    serializer_class = AlbumSerializer

...I run into problems. What's weird is that in the DRF API viewer, everything looks great. I get the expected resulting filtered queryset.

{"data":[{"DT_RowId":"row_12","DT_RowAttr":{"data-pk":12},"rank":12,"name":"Kind of Blue","year":1959,"artist_name":"Miles Davis","genres":"Modal","artist":{"id":9,"name":"Miles Davis"}},{"DT_RowId":"row_5","DT_RowAttr":{"data-pk":5},"rank":5,"name":"Rubber Soul","year":1965,"artist_name":"The Beatles","genres":"Pop Rock","artist":{"id":2,"name":"The Beatles"}},{"DT_RowId":"row_9","DT_RowAttr":{"data-pk":9},"rank":9,"name":"Blonde on Blonde","year":1966,"artist_name":"Bob Dylan","genres":"Folk Rock, Rhythm & Blues","artist":{"id":4,"name":"Bob Dylan"}},{"DT_RowId":"row_1","DT_RowAttr":{"data-pk":1},"rank":1,"name":"Sgt. Pepper's Lonely Hearts Club Band","year":1967,"artist_name":"The Beatles","genres":"Psychedelic Rock, Rock & Roll","artist":{"id":2,"name":"The Beatles"}},{"DT_RowId":"row_10","DT_RowAttr":{"data-pk":10},"rank":10,"name":"The Beatles ("The White Album")","year":1968,"artist_name":"The Beatles","genres":"Experimental, Pop Rock, Psychedelic Rock, Rock & Roll","artist":{"id":2,"name":"The Beatles"}},{"DT_RowId":"row_14","DT_RowAttr":{"data-pk":14},"rank":14,"name":"Abbey Road","year":1969,"artist_name":"The Beatles","genres":"Classic Rock, Pop Rock, Psychedelic Rock","artist":{"id":2,"name":"The Beatles"}},{"DT_RowId":"row_6","DT_RowAttr":{"data-pk":6},"rank":6,"name":"What's Going On","year":1971,"artist_name":"Marvin Gaye","genres":"Soul","artist":{"id":5,"name":"Marvin Gaye"}},{"DT_RowId":"row_7","DT_RowAttr":{"data-pk":7},"rank":7,"name":"Exile on Main St.","year":1972,"artist_name":"The Rolling Stones","genres":"Blues Rock, Classic Rock, Rock & Roll","artist":{"id":6,"name":"The Rolling Stones"}},{"DT_RowId":"row_11","DT_RowAttr":{"data-pk":11},"rank":11,"name":"The Sun Sessions","year":1976,"artist_name":"Elvis Presley","genres":"Rock & Roll","artist":{"id":8,"name":"Elvis Presley"}},{"DT_RowId":"row_8","DT_RowAttr":{"data-pk":8},"rank":8,"name":"London Calling","year":1979,"artist_name":"The Clash","genres":"New Wave, Punk","artist":{"id":7,"name":"The Clash"}}],"recordsFiltered":10,"recordsTotal":10,"draw":1}

But the DataTable fails to load and gives an error:

DataTables warning: table id=albums - Ajax error. For more information about this error, please see http://datatables.net/tn/7

When I use Chrome's inspector, it looks like DataTables is trying to load this URL:

http://127.0.0.1:8000/api/albums/?format=datatables&draw=1&columns%5B0%5D%5Bdata%5D=rank&columns%5B0%5D%5Bname%5D=&columns%5B0%5D%5Bsearchable%5D=false&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=artist.name&columns%5B1%5D%5Bname%5D=artist.name&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=name&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=year&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=genres&columns%5B4%5D%5Bname%5D=genres.name&columns%5B4%5D%5Bsearchable%5D=true&columns%5B4%5D%5Borderable%5D=false&columns%5B4%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B4%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&_=1531170631897

...which results in an internal server error. Here's the entire resulting trace if I go to that url: https://pastebin.com/U8jbeXAA

If have columns without data search failed

I have this:

columns: [
            {
                "className": 'details-control',
                "orderable": false,
                "data": null,
                "defaultContent": '<a class="fa fa-info-circle">'

            }
]

for hide\open menu under the row. And its data=null field. Search not working in this case.

Ordering on a column with many duplicates

If you sort on a column that contains many duplicates (more duplicates than the page size) you might end up iterating through the same rows in the datatable (and completely skip some) as you click through the pages.

I'm not sure what the correct terminology is for this is but it happens because of how order by together with limit & offset works in the database. The easiest way to reproduce this behavior is to set the datatables page size to 1 and then sort by a column where you know there's a lot of duplicates. As you paginate through the table you will notice that some rows show up on multiple pages.

The solution for this is to add a secondary column to sort by (preferably one that contains unique rows such as an id column), that way we will get a strict order of the rows that contains ties.

Pull request #41 or a proposed solution where I'm adding an attribute on the API view itself and then have the filter test for the existence of such attribute before ordering the queryset.

Update: I tried to reproduce the issue with the fixture in test_data.json together with sqlite3 but was unable to trigger the bug. However after changing to a mysql backend I'm able to reproduce the issue by setting the datatable page size to 1 and sort by album year ascending:

...
Page 3: 4 | Bob Dylan | Highway 61 Revisited | 1965
Page 4: 3 | The Beatles | Revolver | 1966 | Pop Rock, Psychedelic Rock
Page 5: 9 | Bob Dylan | Blonde on Blonde | 1966
Page 6: 9 | Bob Dylan | Blonde on Blonde | 1966
Page 7: 1 | The Beatles | Sgt. Pepper's Lonely Hearts Club Band | 1967
...

So the same row is returned for page 5 & 6 and the album:
"2 | The Beach Boys | Pet Sounds | 1966" is never retrieved.

AttributeError after update to 0.5.0

I have written my own ViewSet that extends rest_framework.viewsets.ViewSet

Since the update to 0.5.0 a function I have written for this ViewSet crashes. I have the following function to make sure I get datatables filtering:

    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

After the update to 0.5.0 the call to filter_queryset() errors out on the following line:

total_count = view.get_queryset().count()

Due to the fact that my view does not have a get_queryset() method as can be seen here:

web_1      |   File "/usr/lib/python3.6/site-packages/rest_framework_datatables/filters.py", line 18, in filter_queryset
web_1      |     total_count = view.get_queryset().count()
web_1      | AttributeError: 'ValidationSummaryViewSet' object has no attribute 'get_queryset'

Does this mean I now need to implement a get_queryset() method in my ViewSet? I am not sure I 100% understand this change. Thanks.

Is it possible to send data via POST?

Hi there,

thanks for that great app, it works perfect. Unfortunately DataTables.js, when sending request to DRF API endpoint puts a lot of parameters to URL. That really clogs up logs. There is simple solution, to this problem: send parameters via POST request, described here: https://stackoverflow.com/questions/33862482.

Is it possible to achieve that with DRFD, make it work with POST as well as GET?

Thanks!

HyperlinkedModelSerializer not working

class PatientSerializer(serializers.HyperlinkedModelSerializer):

class Meta:
    model = Patient
    fields = (
        'id', 'patient_manual_id', 'invoice_num', 'name', 'sex', 'age', 'referred_by', 'received_on', 'reported_on',
    )

This code works but when I add 'url' in fields it throws an error...

ImproperlyConfigured at /api/v1/
Could not resolve URL for hyperlinked relationship using view name

Searching and Ordering are not working when using a "dummy" column for row details

I basically copy&pasted the example and replaced it with my own Model class. The datatable is displayed with correct data but searching and sorting doesn't work. I can see server-side the correct parameters are being sent (which field to sort or which search value was entered). However the data always returns the default order and all data.

There is no error message or anything, simply the sorting and filtering seems to be completely ignored. I've also installed django-filter and have it in the settings:

'DEFAULT_FILTER_BACKENDS': (
            'rest_framework_datatables.filters.DatatablesFilterBackend',
            'django_filters.rest_framework.DjangoFilterBackend',
 )

and when using format=json (instead of html), the filtering with DjangoFilterBackend works. Eg. it is the datatables part that somehow not applying the filtering.

I'm aware this isn't exactly very detailed. But I've tried a lot of different options and config but nothing get this to work. Any advice would be welcome.

EDIT:

With debugging I found that get_fields methods always immediately breaks as the first columns data property is empty. In my case the first column is a "dummy" column that contains an icon to expand row details like in this example. Removing that column and it works.

So the actually issue is how to include such a column?

Pagination not working

I am working with 1 million MySQL records. I am just showing the data from the database to the HTML template. But it's taking more than 1 minute to process a single page rendering.

I don't know why pagination is not working of the library?

Can anyone help me to display that large amount of data?

Filtering large dataset is slow

@izimobil

Filtering a table that links back to a large Model dataset is relatively slow. My use case is that the dataset is over a million records and there are about 7 columns the filtering is checking against.

Do you have any recommendations on how to speed this up from the drfd side? Overwriting the filter backend? Specifying which column to filter by?

unused fields filtering removing nested fields

_filter_unused_fields is building list of columns from request, lets assume that there is a field detail.name which is perfectly fine and properly serialized

in the next loop there is a list of keys build in the loop for each record, but this list contains only detail key which is not on the previously built list of columns - in this moment data dissapears from the response... of course, there is an option to keep data despite missing key (datatables_always_serialize list) - but in my opinion for the nested fields default approach should be to keep them without additional hassle

search disabled with filter backend

Hi @izimobil ,

drf-datatables search field works fine.
When I add in my class a DjangoFilterBackend to filter by id, the search bar stops working.
Here is my class in my api_views.py

class ExResultListUp(ListAPIView):
        queryset = ExResultUp.objects.all().order_by('overlap')
        serializer_class = ExResultSerializerUp
        filter_backends = (DjangoFilterBackend,)
        filter_fields = ('id',)

When I comment this line filter_backends = (DjangoFilterBackend,), the search bar in datatables works fine.

Search failing for SlugField

i have the following:

class Offer(models.Model):
    short_name = models.CharField(max_length=64)

class Instance(models.Model):
    offer = models.ForeignKey(Offer, on_delete=models.SET_NULL, blank=True, null=True)

class InstanceSerializer(serializers.ModelSerializer):
    offer = serializers.SlugRelatedField(read_only=True, slug_field='short_name')

It seems like typing anything in the search field will result in the following:

Traceback (most recent call last):
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/core/handlers/exception.py", line 35, in inner
    response = get_response(request)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/core/handlers/base.py", line 128, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/viewsets.py", line 103, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/views.py", line 483, in dispatch
    response = self.handle_exception(exc)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/views.py", line 443, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/views.py", line 480, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/mixins.py", line 40, in list
    queryset = self.filter_queryset(self.get_queryset())
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework/generics.py", line 152, in filter_queryset
    queryset = backend().filter_queryset(self.request, queryset, self)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/rest_framework_datatables/filters.py", line 66, in filter_queryset
    queryset = queryset.filter(q).distinct()
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/query.py", line 836, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/query.py", line 854, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1248, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1266, in _add_q
    current_negated, allow_joins, split_subq)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1272, in _add_q
    split_subq=split_subq,
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1210, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/Users/vng/.virtualenvs/prometheus/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1071, in build_lookup
    raise FieldError('Related Field got invalid lookup: {}'.format(lookup_name))
django.core.exceptions.FieldError: Related Field got invalid lookup: icontains
[24/Aug/2018 07:49:24] "GET /instances/api/?format=datatables&draw=2&columns%5B0%5D%5Bdata%5D=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=circle&columns%5B1%5D%5Bname%5D=&columns%5B1%5D%5Bsearchable%5D=false&columns%5B1%5D%5Borderable%5D=false&columns%5B1%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B1%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B2%5D%5Bdata%5D=domain&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=account&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=offer&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=lander&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&columns%5B6%5D%5Bdata%5D=cloaker_category&columns%5B6%5D%5Bname%5D=&columns%5B6%5D%5Bsearchable%5D=true&columns%5B6%5D%5Borderable%5D=true&columns%5B6%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B6%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B7%5D%5Bdata%5D=last_updated_at&columns%5B7%5D%5Bname%5D=&columns%5B7%5D%5Bsearchable%5D=false&columns%5B7%5D%5Borderable%5D=true&columns%5B7%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B7%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B8%5D%5Bdata%5D=8&columns%5B8%5D%5Bname%5D=&columns%5B8%5D%5Bsearchable%5D=false&columns%5B8%5D%5Borderable%5D=false&columns%5B8%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B8%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B9%5D%5Bdata%5D=ip_address&columns%5B9%5D%5Bname%5D=&columns%5B9%5D%5Bsearchable%5D=true&columns%5B9%5D%5Borderable%5D=true&columns%5B9%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B9%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B10%5D%5Bdata%5D=summary&columns%5B10%5D%5Bname%5D=&columns%5B10%5D%5Bsearchable%5D=false&columns%5B10%5D%5Borderable%5D=true&columns%5B10%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B10%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B11%5D%5Bdata%5D=deploy_money&columns%5B11%5D%5Bname%5D=&columns%5B11%5D%5Bsearchable%5D=false&columns%5B11%5D%5Borderable%5D=true&columns%5B11%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B11%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B12%5D%5Bdata%5D=deploy_both&columns%5B12%5D%5Bname%5D=&columns%5B12%5D%5Bsearchable%5D=false&columns%5B12%5D%5Borderable%5D=true&columns%5B12%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B12%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B13%5D%5Bdata%5D=last_deployed&columns%5B13%5D%5Bname%5D=&columns%5B13%5D%5Bsearchable%5D=false&columns%5B13%5D%5Borderable%5D=true&columns%5B13%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B13%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B14%5D%5Bdata%5D=safepage_url&columns%5B14%5D%5Bname%5D=&columns%5B14%5D%5Bsearchable%5D=false&columns%5B14%5D%5Borderable%5D=true&columns%5B14%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B14%5D%5Bsearch%5D%5Bregex%5D=false&columns%5B15%5D%5Bdata%5D=comment&columns%5B15%5D%5Bname%5D=&columns%5B15%5D%5Bsearchable%5D=false&columns%5B15%5D%5Borderable%5D=true&columns%5B15%5D%5Bsearch%5D%5Bvalue%5D=&columns%5B15%5D%5Bsearch%5D%5Bregex%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=desc&start=0&length=25&search%5Bvalue%5D=2&search%5Bregex%5D=false&_=1535068163637 HTTP/1.1" 500 31741

Serverside filtering not working, when model has Foreign key

I have a fairly complex set of models, that use Foreign keys. Unfortunately filtering does not seem to work when a Field contains a Foreign key. If you try to filter the server responds with a 500 internal server error.
The actual error message is the following: Related Field got invalid lookup: icontains.

I know this happens, because django-rest-framework-datatables tries to use icontains on a foreign key, which is not possible.

I now wonder if something can be done, or if there is at least something I can do to fix this issue?

Assuming that a column with no data attribute is the last column in a row breaks filtering.

I use the first column in the datatable as a checkbox that can be toggled for selecting fields for bulk actions and so it doesn't have a data attribute defined. Assuming that a column with no data attribute is the last column in a row breaks filtering since the get_fields method stops processing the fields as soon as it hits one with no data key.

Change behavior of json delivered by rest api

Hello,
I wonder if it's is normal to change the behavior of json request, eg. ?format=json

I have different API and I just want to use this library for one of them.

For exemple,

{"id":1,"label":"20181002-165328","bounds":[0,-1]},
{"id":2,"label":"20181002-165328","bounds":[0,-1]]

becomes

{"count":2,"next":null,"previous":null,"results":[{"id":1,"label":"20181002-165328","bounds":[0,-1],{"id":2,"label":"20181002-165328","bounds":[0,-1]}

Is it the expected behavior ?

Regards

multi_filter columns logical connection

First of all, thanks for the great work on implementing this plugin, it saved me a lot of time :)

I have a small issue that i try to explain with the multi_filter example of the official DataTables site (https://datatables.net/examples/api/multi_filter.html)

in this example: when you filter the name column by "Angelica" you get one row:
image

when you filter the name column by "Accountant" you get two rows:
image

combining both you get zero rows (because the one Angelica is no accountant):
image

So clearly the column filters are linked logically with AND

Your plugin does it differently server-side. The single column filters work fine. But if you combine them you would get three rows: the two accountants and Angelica.

The reason: In line 43 and 45 the filters.py the individual column filters are linked with OR
image

I guess there should be AND operations instead to match the way DataTables is filtering multiple columns client-side.
Locally i replaced the two occurences with &= on my computer and it works as expected.

Thanks for reading,
best regards Christoph

DEFAULT_PAGINATION_CLASS not changing to custom paginator

I created a custom pagintor that skips running a SELECT COUNT(*) AS __count FROM query.

I have a large database of 6.5million rows so a count query takes a little over 2 seconds.

When I visit the URL http://127.0.0.1:8000/products/api/ the SELECT COUNT query is not run as I would expect.

When I visit the URL http://127.0.0.1:8000/products/api/?format=datatables a SELECT COUNT query is run which causes the table to take more time to load.

Anyone have any idea on how to fix this? or have a better solution to not run the SELECT COUNT query everytime I load a new page?

hide from swagger

how remove from swagger page-field:

A page number within the paginated result set.

?

limitted format detection

drf-datatables in the paginator is using a test on 'format' request queryset to switch on/off datatables integration, however DRF allow that format can be specified in 2 ways:

  • as a request query variable
  • as a suffix

drf-datatables is missing latter one, paginator may have access to this information via the 'view' parameter (view.format_kwargs or as a key kwargs of the view.kwargs dictionary)

view.kwargs looks a best option, as it is always there, for the view.format_kwargs hasattr should be used

format suffix has a precedence over request query variable

last but as well important is that name of the url variable as well as request queryset variable can be overriden specyfing FORMAT_SUFFIX_KWARG and/or URL_FORMAT_OVERRIDE - so those options should be used instead hardcoded "format"

DRF Token Aunthentication Support

I have followed the tutorial and have found nothing on how to integrate this library with DRF token authentication (my API must use that). When I make the requests to the url DRF blocks the request because it has no validation token. All I would need to do is attach a header to the request. Is there a way to do this?

Using a null/empty column in the Datatables front-end breaks search and ordering in the REST API

Sometimes I use datatables with a column of checkboxes in the front-end for selection. During a request, this column is set as empty strings. When drf-datatables encounters an empty string, it breaks out and returns no fields which in turn breaks search and ordering.

Example: A dummy column like this:

{
                "data": null,
                "defaultContent": '',
                'searchable': false,
                'orderable': false,
                'className': 'dt-body-center',
                'render': function (data, type, row, meta) {
                        return `<input type="checkbox" class="item_select_checkbox"/>`;
                    }
                }
            }

will result in params like:

'format': ['datatables'], 'draw': ['6'], 'columns[0][data]': [''], 'columns[0][name]': [''], 'columns[0][searchable]': ['false'], 'columns[0][orderable]': ['false'], 'columns
[0][search][value]': [''], 'columns[0][search][regex]': ['false'],

Because of this line: any column like the above will result in an empty list of fields which will break search and ordering.

Planned timeline for python 2 support?

I'd like to know how you (@izimobil ) feel about Python 2 support, since I'm trying to develop optional support for django-filters and I'm having real trouble carrying Python 2 along.

It's no problem raising a SkipTest exception if the django-filters module is not present in python 3, but in Python 2 this will cause an error and this would make the tests for the new functionality quite complicated.

Support Django 3

Are you thinking to upgrade to django 3? Will be release in december 2019.
Im using django (dev3), and get this error (because "six" library will not be used in django 3).
This error shows only when tried to use pagination. rest of code as far i know works like a charm.

ImportError: Could not import 'rest_framework_datatables.pagination.DatatablesPageNumberPagination' for API setting 'DEFAULT_PAGINATION_CLASS'. ImportError: cannot import name 'six' from 'django.utils' (/home/xxx/django/django/utils/__init__.py).

Thank you.

support for yadcf?

There is something called yadcf (https://github.com/vedmack/yadcf) which makes it easy to add filters to datatables. For it to work properly when serverside=true, the server has to output some extra data.
I initially thought this is something that could be added to django-rest-framework-datatables but it's probably too specific and can't be made generic.
So just wondering if it's possible to modify what django-rest-framework-datatables outputs and where the best place would be to do it?

The extra data I need to output is all the possible values for a certain column before filtering, so that a select can be shown on the front end.

How to send custom data to the Datatable?

In my datatable I have two columns that have integer values and I need to show the sum of the values.
It can be done easily while "serverSide": false is set with below code.

drawCallback: function () {
                    var sum_cell = $('#tasktableV').DataTable().column(5).data().sum();
                    var sum_para = $('#tasktableV').DataTable().column(6).data().sum();
                    $('#cell').html(sum_cell);
                    $('#parameter').html(sum_para);}

But while "serverSide": true is set the above drawCallback returns the sum according to the current page only. So in this case I would need to provide the SUM data from the server end. So how could I solve this problem?

models.py:

class taskvolume(models.Model):
    u_id = models.UUIDField(default=uuid.uuid4, editable=True, unique=False)
    date = models.DateField(default=timezone.now)
    teams = models.CharField(max_length=50, choices=team_choices, blank=True)
    domain = models.CharField(max_length=20, choices=domain_choices, blank=True)
    type = models.ForeignKey(type_field, to_field='type', blank= True, on_delete=models.SET_NULL, 
    null=True)
    cell_count = models.IntegerField()
    parameter_count = models.IntegerField()

serializers.py

class TaskVolumeSerializer(serializers.ModelSerializer):
    type_name= serializers.ReadOnlyField(source='type.type')
    type= TypeFieldSerializer()
    DT_RowId = serializers.SerializerMethodField()
    DT_RowAttr = serializers.SerializerMethodField()

    def get_DT_RowId(self, task_assign):
        return 'row_%d' % task_assign.pk

    def get_DT_RowAttr(self, task_assign):
        return {'data-pk': task_assign.pk}
    class Meta:
        model= taskvolume
        fields= ('id','DT_RowId', 'DT_RowAttr','u_id','date','teams','domain','type_name','type','cell_count',  
        'parameter_count'
        )

views.py

class TaskVolumeViewSet(generics.ListAPIView):
    queryset = taskvolume.objects.all().order_by('-date')
    serializer_class = TaskVolumeSerializer

CRUD Operations

Hi, thank you for this very useful datatable component. Does this component also support CRUD operations (using the REST API)?

Search and filter doing nothing in custom ViewSet

Hi,

I have a django rest application with multiple viewsets that are working correctly with datatables and this package. However, I have recently made a custom viewset which overrides the list() method of the viewset. Therefore, the ?format=datatables is not working correctly (the list function is overridden and only that functionality happens). Sorting, paging, and filtering are not working correctly. How can I also get the datatables formatted endpoint on server side processing to correctly paginate, filter, and search even though I have overridden the list() method of my viewset.

I tried the following which is pretty much the same as the docs:

Are my annotations breaking things?

class ValidationSummaryViewSet(viewsets.ViewSet):
    queryset = TargetConfirmation.objects.values('target_prediction__id').annotate(
        sample_id=F('target_prediction__id'), num_selected=Count('selected'), num_validated=Count('validated'),
        num_has_standard=Count('has_standard'))
    serializer_class = ValidationSummarySerializer

    def list(self, request):
        serializer = self.serializer_class(self.queryset, many=True)
        return Response(serializer.data)

Thanks!

searching failing in multiple scenarios

I've found a multiple scenarios where existing column search is failing badly:

  • search on fields that are foreign keys or numbers (eg. integers) - this will fail on "proper" databases (not sqlite)
  • search on fields that are aliases to some other columns, e.g.:
detail_name = serializers.CharField(source='detail.name', read_only=True)

existing code assumes incorrectly that field name is the database field to query

most of those searches will fail twice - on "general" search - where top search field is used and then second time on the specific field

I do not have a clear idea how to resolve this, but those my first ideas:

  • there should be an implementation that is similar to the existing ones - where searchable fields will be specified on python side - not pushed from request - this is potentially a security/performance leak
  • there should be an option that is defining which fields are taken into account in "global" search
  • there should be a detection and/or specification of default search operators per field type, where a safe options should be set as defaults (e.g. __exact or __iexact) and user could override them (eg. __icontains/__istartswith etc.)
  • maybe there will be an option to use existing filtering backends in combination with this one?

Multiple search filter not working

Hi Expert,

When I try to search with multiple columns I am getting the 500 error. Please help me to fix it.

JS CODE:
`"use strict";

var KTDatatablesSearchOptionsAdvancedSearch = function() {

$.fn.dataTable.Api.register('column().title()', function() {
	return $(this.header()).text().trim();
});

var initTable1 = function() {
	// begin first table
	var table = $('#kt_table_1').DataTable({
		responsive: true,
		colReorder: true,
		// rowGroup: {dataSrc: 'SID'},

		// Pagination settings
		dom: `<'row'<'col-sm-12'tr>>
		<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7 dataTables_pager'lp>>`,
		// read more: https://datatables.net/examples/basic_init/dom.html

		lengthMenu: [5, 10, 20, 30, 50],

		pageLength: 20,

		language: {
			'lengthMenu': 'Display _MENU_',
		},

		searchDelay: 500,
		processing: true,
		serverSide: true,
		ajax: {
			url: '/patch/api/dt/?format=datatables',
			type: 'GET',
			data: {
				// parameters for custom backend script demo
				columnsDef: ['SID', 'DBSID','DC',"HOST","os_version","MEMORY",'TYP','ZHCODE','EUDP','SYSTEMROLE'],
			},
		},
		columns: [
								{'data': 'SID', 'name': 'SID', 'autoWidth':true},
								{'data': 'DBSID', 'name': 'DBSID', 'autoWidth':true},
								{'data': 'ZHCODE', 'name': 'ZHCODE', 'autoWidth':true},
								{'data': 'DC', 'name': 'DC', 'autoWidth':true},
								{'data': 'TYP', 'name': 'TYP', 'autoWidth':true},
								{'data': 'HOST', 'name': 'HOST', 'autoWidth':true},
								{'data': 'os_version', 'name': 'os_version', 'autoWidth':true},
								{'data': 'MEMORY', 'name': 'MEMORY', 'autoWidth':true},
								{'data': 'EUDP', 'name': 'EUDP', 'autoWidth':true},
								{'data': 'SYSTEMROLE', 'name': 'SYSTEMROLE', 'autoWidth':true}
							],

		columnDefs: [
			{
				targets:'_all',
			className: 'dt-center',
		},


			{
				targets: 2,
				className: 'dt-center',
				render: function(data, type, full, meta) {
					var status = {
						'ZH006': {'title': 'ZH006', 'state': 'warning'},
						'ZH001': {'title': 'ZH001', 'state': 'warning'},
						'ZH029': {'title': 'ZH029', 'state': 'accent'},
						'ZH019': {'title': 'ZH019', 'state': 'accent'},
						'ZH037': {'title': 'ZH037', 'state': 'focus'},
						'ZH002': {'title': 'ZH002', 'state': 'danger'},
						'ZH005': {'title': 'ZH005', 'state': 'info'},
					};
					if (typeof status[data] === 'undefined') {
						return data;
					}
					return '<span class="kt-badge--' + status[data].state + '"></span>&nbsp;' +
						'<span class="kt-font-bold kt-font-' + status[data].state + '">' + status[data].title + '</span>';
				},
			},
			{
				targets: -2,
				className: 'dt-center',
				render: function(data, type, full, meta) {
					var status = {
						false: {'title': 'PROD', 'class': '<a href="#" class="btn btn-sm btn-clean btn-icon btn-icon-md" title="NON-EUDP"><i class="fa fa-times-circle k-font-success"></i></a>'},
						true: {'title': 'VLAB', 'class': ' <a href="#" class="btn btn-sm btn-clean btn-icon btn-icon-md" title="EUDP"><i class="fa fa-check-circle"></i></a>'},
					};
					if (typeof status[data] === 'undefined') {
						return data;
					}
					return status[data].class;
				},
			},
		],
	});

	var filter = function() {
		var val = $.fn.dataTable.util.escapeRegex($(this).val());
		table.column($(this).data('col-index')).search(val ? val : '', false, false).draw();
	};

	var asdasd = function(value, index) {
		var val = $.fn.dataTable.util.escapeRegex(value);
		table.column(index).search(val ? val : '', false, true);
	};

	$('#m_search').on('click', function(e) {
		e.preventDefault();
		var params = {};
		$('.kt-input').each(function() {
			var i = $(this).data('col-index');
			if (params[i]) {
				params[i] += '|' + $(this).val();
			}
			else {
				params[i] = $(this).val();
			}
		});
		$.each(params, function(i, val) {
			// apply search params to datatable
			table.column(i).search(val ? val : '', true);
		});
		table.table().draw();
	});

	$('#m_reset').on('click', function(e) {
		e.preventDefault();
		$('.kt-input').each(function() {
			$(this).val('');
			table.column($(this).data('col-index')).search('', false, false);
		});
		table.table().draw();
	});

	$('#m_datepicker').datepicker({
		todayHighlight: true,
		templates: {
			leftArrow: '<i class="la la-angle-left"></i>',
			rightArrow: '<i class="la la-angle-right"></i>',
		},
	});


};

return {

	//main function to initiate the module
	init: function() {
		initTable1();
	}
};

}();

jQuery(document).ready(function() {
KTDatatablesSearchOptionsAdvancedSearch.init();
});
`

Server-side :
`
class Prodclddata(viewsets.ModelViewSet):

try:
    queryset = COMPUTED_HOST_DETAILS.objects.filter(IS_VLAB=False)
    serializer_class = SystemSerializer
except Exception as e:
    raise

`
Search:
image

ERROR
image

Problems displaying and filtering Method and ReadOnly Fields

It appears that the filter logic doesn't have a way to deal with calculated fields (i.e. SerializerMethodField() or ReadOnlyField()).

Currently, if you attempt to include one of these fields as a column, it will run the field through filter_queryset() in filters.py. Unfortunately, since they are not fields on the model, it returns the following error:

FieldError... Cannot resolve keyword.

This happens even when setting the column to 'searchable': false.

If I set the name: field in columns to a different field in the model, it will display the data. However, it is not searchable or filterable. Doing so returns the following error:

Related Field got invalid lookup: icontains

It seems that the way forward would be to provide a separate query param that stipulates what the filter field should be for a given column. However, I don't think that Datatables has this functionality built in with how it formats url query params for server side processing.

Perhaps it would be possible to repurpose the columns[i][name] param for this purpose, but that seems hacky-af.

Post request Api

Please advise me on it. Can I make the post request Api in python shell using same URL. Or will have make the another .py file for post request api.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.