0

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.

Saran Prasad
  • 125
  • 2
  • 13

1 Answers1

3

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.

Dipendra bhatt
  • 729
  • 5
  • 14
  • Initially i tried like that. Showing url not found when debugging . So i changed it like this. My doubt is actually I'm using namespace. So how can use ?format=datatables in the url. – Saran Prasad Apr 09 '20 at 08:49
  • You just add the ?format=datatables string at the end of url. I have updated the answer to provide a library link and provided a example ajax call. – Dipendra bhatt Apr 09 '20 at 09:14
  • I tried like you said, Now i am getting a error, TypeError at /f-admin/perms/ __init__() takes 1 positional argument but 2 were given. In browser console..Error 500. – Saran Prasad Apr 09 '20 at 10:55
  • i commented this in my url: # router = routers.DefaultRouter() # router.register(r'perms', views.PermissionViewSet) is this required.? – Saran Prasad Apr 09 '20 at 11:03
  • Edit your question and putt all the complete information including the urls.py file. Otherwise its difficult for me to identify the issue just from this. And if possible put the stack trace also. – Dipendra bhatt Apr 09 '20 at 11:09
  • its all included. url, views,.htm files everythng..even serializers too. – Saran Prasad Apr 09 '20 at 11:11
  • 1
    Uh, its not working coz the url routing is wrong. You need to write this url(r'^perms/$', PermissionViewSet.as_view({"get": "list"}), name="perms"). Here we are supplying the function to map for GET request. And you can remove that router code. This should suffice. – Dipendra bhatt Apr 09 '20 at 12:06
  • Thank you very much, Now its working. Can you update the answer so i can verify it. – Saran Prasad Apr 09 '20 at 12:11