Search code examples
djangodjango-rest-frameworkdatatablesserver-sidedjango-datatable

Is there anything i missed in configuring django-rest-framework-datatables, getting error "DataTables warning: table id=test - Ajax error"


I tried to configure datatables with rest frame work, i'm getting error when page loads all the datatables fields like pagination, search and title is showing but no data is showing. what might be the reason?

serializers.py

class PermissionSerializer(serializers.ModelSerializer):
class Meta:
    model = Permission
    fields = (
        'name', 'code', 'app',
    )

views.py

from rest_framework import viewsets
from .serializers import PermissionSerializer

class PermissionViewSet(viewsets.ModelViewSet):
    queryset = Permission.objects.all()
    serializer_class = PermissionSerializer


class ViewallPerms(View):
    def get(self, request):
        context = {
            'a' : 'a',
        }
        return render(request, 'flamika_admin/view_allpermissions.html', context)

urls.py

 url(r'^perms/$', views.PermissionViewSet, name='perms'),
 path('all-perms', login_required(views.ViewallPerms.as_view(), login_url='f_admin:admin_login'), name='all-perm'),

view_allpermissions.html

<script src="https://code.jquery.com/jquery-1.8.0.min.js"></script>

<div class="row">
    <div class="col-sm-12 col-xs-12">
        <table id="test" class="table table-striped table-bordered" style="width:100%">
        <thead>
            <tr>
                <th>Code</th>
                <th>Name</th>
                <th>App</th>
            </tr>
        </thead>

    </table>
</div>
</div>
<script>
    $(document).ready(function() {
        var table = $('#test').DataTable({
            "serverSide": true,
            dataSrc: "",
            "ajax": "{% url 'flamika_admin:perms' %}",
            "columns": [
                {"data": "name"},
                // Use dot notation to reference nested serializers.
                // This data: could alternatively be displayed with the serializer's ReadOnlyField as well, as seen in the minimal example.
                {"data": "code"},
                {"data": "app"},
           ]
        });
        $('.btn-decade').on('click', function() {
            table.columns().search('');
            var rel = $(this).attr('rel');
            if (rel) {
                table.columns(3).search('^' + rel + '[0-9]$', true).draw();
            } else {
                table.draw();
            }
        });
        $('#albums_minimal').DataTable({
           "search": {"regex": true},
           "language": {"searchPlaceholder": "regular expression"}
        });
    });
    </script>

please let me know where i went wrong, is this right way to configure server-side with datatables. Please correct me. I wanted to display all data in that model.


Solution

  • You forgot to add "?format=datatables" in your ajax API call. Datatables expect response in a certain way to display it properly and if you have correctly configured django-rest-framework-datatables(follow the docs, its pretty much straightforward), the library checks if the format parameter is set to datatables or not. In case its not set, the default pagination format of DRF is used(which does not work with datatables, your case) where if set then django-rest-framework-datatables formats the response in the correct way for datatables.

    Note: So i wanted to mention if you would like to use django's reverse feature even in js file there is a good library i will link https://github.com/ierror/django-js-reverse.

    Use this to reverse and add ?format=datatables to the url or you could write the url manually. E.g.

    "ajax": {
            "url": "http://127.0.0.1:8000/perms/?format=datatables",
            "type": "GET",
            "headers": {
                    /* any headers */
           },
           "dataSrc": "Mention your data source from the respone "
    }
    

    Check the url there, make sure its right. I have just written that as an example.

    Update: The url routing for PermissionViewSet was incorrect. Correct form is:

    url(r'^perms/$', PermissionViewSet.as_view({"get": "list"}), name="perms")
    

    Notice the mapping of request method.