I am trying to incorporate DataTables Editor into a Django REST API. While I am able to get the datatable to display, the create button will not work and returns
"POST /dashboard/api/investigator/ HTTP/1.1" 400 160
I've setup the editor according to the documentation but the API still won't seem to accept it. The 400 status code indicates it is a bad request, but what does the 160 mean? Can anyone provide input if I setup the datatable wrong?
urls.py
from django.urls import path, include
from . import views
from rest_framework import routers
from .views import StudyList, StudyDetail, InvestigatorView
app_name = 'dashboard'
router = routers.DefaultRouter()
router.register('study', views.StudyView)
router.register('investigator', views.InvestigatorView)
router.register('lead', views.LeadView)
router.register('institution', views.InstitutionView)
router.register('site', views.SiteView)
investigator_list = InvestigatorView.as_view({
'get': 'list',
'post': 'create'
})
investigator_detail = InvestigatorView.as_view({
'get': 'retrieve',
'PUT': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
urlpatterns = [
path('', views.datatables, name='datatable'),
path('investigator/', views.datatables_investigator, name='datatables_investigator'),
path('api/', include(router.urls)),
path('api/investigator/', investigator_list, name='InvestigatorList'),
path('api/investigator/<int:pk>', investigator_detail, name='InvestigatorDetail'),
path('api/study/', StudyList.as_view(), name='StudyList'),
path('api/study/<int:pk>/', StudyDetail.as_view(), name='StudyDetail')
]
datatables_investigator.html
{% extends 'base_datatables_editor.html' %}
{% block content %}
<h1 style="text-align: center; padding-top: 1em; padding-bottom: 1em;">Investigators</h1>
<div class="row">
<div class="col-sm-12">
<table id="InvestigatorDataTable" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Institution</th>
</tr>
</thead>
</table>
</div>
</div>
{% endblock content %}
{% block extra_js %}
<script>
var editor;
$(document).ready(function() {
editor = new $.fn.dataTable.Editor( {
ajax: {
create: {
type: "POST",
url: 'http://127.0.0.1:8000/dashboard/api/investigator/'
contentType: 'application/json',
data: function ( d ) {
return JSON.stringify( d );
},
edit: {
type: "PUT",
url: "http://127.0.0.1:8000/dashboard/api/investigator/_id_"
},
remove: {
type: "DELETE",
url: "http://127.0.0.1:8000/dashboard/api/investigator/_id_"
}},
table: '#InvestigatorDataTable',
data: "symbol",
defaultContent: "",
contentType: 'application/json',
csrfmiddlewaretoken: window.CSRF_TOKEN,
table: '#InvestigatorDataTable',
idSrc: "id",
dataSrc: "data",
fields: [ {
label: "ID:",
name: "id"
}, {
label: "Last Name:",
name: "last_name"
}, {
label: "First Name:",
name: "first_name"
}, {
label: "Email:",
name: "email"
}, {
label: "Institution:",
name: "institution",
///type: "select",
///placeholder: "Select an institution"
}, {
label: "Created At:",
name: "created_at",
type: "datetime",
def: function () { return new Date(); },
displayFormat: 'YYYY-MM-DD HH:mm:ss.SSSS'
///2022-05-19T17:59:46.167754Z
}]
});
$('#InvestigatorDataTable').DataTable({
serverSide: true,
ajax: 'http://127.0.0.1:8000/dashboard/api/investigator/?format=datatables',
dom: 'Bfrtrip',
columns: [
{data: "last_name", },
{data: "first_name",},
{data: null, render: function ( data, type, row ) {
return data.first_name + " " + data.last_name
}},
{data: "email", orderable: false},
{data: "institution.name", name: "institution.name", orderable: true},
],
columnDefs: [
{ targets: [2, 3, 4,], visible: true},
{ targets: '_all', visible: false }
],
select: true,
buttons: [
{ extend: "create", editor: editor },
{ extend: "edit", editor: editor },
{ extend: "remove", editor: editor }
]
});
});
</script>
{% endblock %}
serializers.py
from rest_framework import serializers
from dashboard.models import Study, Investigator, Lead, Institution, Site
class InstitutionSerializer(serializers.ModelSerializer):
class Meta:
model = Institution
fields = ('name', 'dept')
class InvestigatorSerializer(WritableNestedModelSerializer, serializers.ModelSerializer):
institution = InstitutionSerializer
class Meta:
model = Investigator
fields = ('__all__')
depth = 1
datatables_always_serialize = ('id',)
views.py
from django.shortcuts import render, redirect
from .models import Study, Investigator, Lead, Institution, Site
from .forms import StudyForm
from django.views.decorators.csrf import csrf_exempt
from rest_framework import viewsets, generics
from rest_framework.permissions import AllowAny
from .serializers import StudySerializer, InvestigatorSerializer, LeadSerializer, InstitutionSerializer, SiteSerializer
# Datatable Views
@csrf_exempt#@csrf_protect#@ensure_csrf_cookie
def datatables(request):
return render(request, 'datatables.html')
def datatables_investigator(request):
return render(request, 'datatables_investigator.html')
#API Views
class InvestigatorView(viewsets.ModelViewSet):
queryset = Investigator.objects.all()
serializer_class = InvestigatorSerializer
permission_classes = [AllowAny]
class InstitutionView(viewsets.ModelViewSet):
queryset = Institution.objects.all()
serializer_class = InstitutionSerializer
models.py
class Investigator(models.Model):
id = models.AutoField(unique=True, primary_key=True)
last_name = models.CharField(max_length=50)
first_name = models.CharField(max_length=50)
email = models.CharField(max_length=50)
created_at = models.DateTimeField(auto_now_add=True)
institution = models.ForeignKey('Institution', models.DO_NOTHING, )
class Meta:
managed = True
db_table = 'investigator'
def __str__(self):
return str(self.last_name)
Request being sent In case the image beneath doesn't appear, here is the XHR response sent ~{"data":{"0":{"last_name":"test2","first_name":"test2","email":"test2","institution":"1"}},"action":"create"}
Using the djangorestframework-datatables-editor python package, the URL should be set to http://127.0.0.1:8000/dashboard/api/investigator/editor/?format=datatables
not http://127.0.0.1:8000/dashboard/api/investigator/
. This what allows it to read the data within the editor format.