Integrating DataTables plugin with django framewor

2019-04-09 22:44发布

问题:

I am a beginner in django framework and DataTables. Currently, I am trying to load a jquery DataTable with the data coming back from the server. I have built an api using django REST framework to pass the data to DataTables. However, I am not able to load the DataTable from the json data from the server. Please find below my code snippets and pleas tell me if I am missing anything.

the index.html looks like following.

<table id="packages_table" class="table table-striped table-bordered">
        <thead>
            <tr>
                <th>User Name</th>
                <th>First Name</th>
                <th>Email</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td></td>
                <td></td>
                <td></td>
            </tr>
        </tbody>
     </table>
<script type="text/javascript">
    $(document).ready(function () {
        $('#packages_table').dataTable({
            ajax: 'http://127.0.0.1:3434/user/',
            columns: [
                { "data": "username"},
                { "data": "first_name"},
                { "data": "email"},
            ]
        });
    });
</script>

urls.py, where I have defined the viewset, serializer and router looks like this.

class UserSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = User
        fields = ('username', 'first_name', 'email', 'is_staff')

# ViewSets define the view behavior.

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer


# Routers provide an easy way of automatically determining the URL conf.
router = routers.DefaultRouter()
router.register(r'user', UserViewSet)

# Wire up our API using automatic URL routing.
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', include(datagrid_urls)),
    #configure to use the browsable API by adding REST framework's login and logout views
    url(r'^', include(router.urls)),
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]  + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

And, below is the json data from the url.

[
    {
        "url": "http://127.0.0.1:3434/user/2/",
        "username": "morgoth",
        "first_name": "morgoth",
        "email": "duke.valafar@gmail.com",
        "is_staff": true
    },
    {
        "url": "http://127.0.0.1:3434/user/3/",
        "username": "anna",
        "first_name": "",
        "email": "anna@anna.com",
        "is_staff": false
    },
    {
        "url": "http://127.0.0.1:3434/user/4/",
        "username": "adam",
        "first_name": "",
        "email": "ada@abc.com",
        "is_staff": false
    }
]

And here is my debug bookmarklet

回答1:

SOLUTION

You need to use the following initialization code to match your data structure:

$('#packages_table').dataTable({
    ajax: {
        url: 'http://127.0.0.1:3434/user/',
        dataSrc: '' 
    },
    columns: [
        { "data": "username"},
        { "data": "first_name"},
        { "data": "email"},
    ]
});

From the dataSrc option description:

Note that if your Ajax source simply returns an array of data to display, rather than an object, set this parameter to be an empty string.

DEMO

$(document).ready(function() {
  // AJAX emulation for demonstration only
  $.mockjax({
    url: 'arrays.txt',
    responseTime: 200,
    response: function(settings) {
      this.responseText = [
        {
          "url": "http://127.0.0.1:3434/user/2/",
          "username": "morgoth",
          "first_name": "morgoth",
          "email": "duke.valafar@gmail.com",
          "is_staff": true
        }, {
          "url": "http://127.0.0.1:3434/user/3/",
          "username": "anna",
          "first_name": "",
          "email": "anna@anna.com",
          "is_staff": false
        }, {
          "url": "http://127.0.0.1:3434/user/4/",
          "username": "adam",
          "first_name": "",
          "email": "ada@abc.com",
          "is_staff": false
        }
      ]
    }
  });

  var table = $('#packages_table').DataTable({
    ajax: {
      url: "arrays.txt",
      dataSrc: ""
    },
    columns: [
        { "data": "username" },
        { "data": "first_name"},
        { "data": "email"}
    ]    
  });

});
<!DOCTYPE html>
<html>

<head>
  <meta charset="ISO-8859-1">

  <link href="//cdn.datatables.net/1.10.7/css/jquery.dataTables.min.css" rel="stylesheet" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
  <script src="http://vitalets.github.com/x-editable/assets/mockjax/jquery.mockjax.js"></script>

</head>

<body>
  <table id="packages_table" class="display">
    <thead>
      <tr>
        <th>User Name</th>
        <th>First Name</th>
        <th>Email</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
  </table>
</body>

</html>



回答2:

Gyrocode.com was absolutely correct about mentioning the dataSrc field. However, even that did not work as a solution. After a lot of trial and error, I found that I was using DataTables version 1.9.4, whereas in 1.10 version the syntax is very different to call the ajax function.

Hence to make it work, ajax field has to be replaced by sAjaxSource. Detailed reference to this conversion is covered in this link. However, the best solution, is, of-course to update the DataTables version to 1.10.

I would like to mention DataTables Debugger tool, which really helped me to debug this issue and I would like to recommend it to people who might get stuck in future while debugging DataTables related issue.