DataTables with Django Rest Framework New/Edit/Delete Buttons not working
I am trying to incorporate DataTables Editor into a Django REST API I made. While I am able to get the datatable to display, the create/edit/delete buttons to do not work. I want to focus on just the edit function for now and hopefully the answer can be applied to the create/delete functions as well. Every time I select the edit button and chose an entry to edit I am returned
PUT http://127.0.0.1:8000/dashboard/api/investigator/1 403 (Forbidden)
I am able to edit the entry but the request is not processed which makes me believe it is either my datatables being setup wrong or the REST API not connecting with datatables.
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/'
},
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',
idSrc: "id",
fields: [ {
label: "Last Name:",
name: "last_name"
}, {
label: "First Name:",
name: "first_name"
}, {
label: "Email:",
name: "email"
}, {
label: "Institution:",
name: "data.institution.name",
type: "select"
}]
});
$('#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 rest_framework.serializers import ReadOnlyField
from dashboard.models import Study, Investigator, Lead, Institution, Site
from drf_writable_nested import WritableNestedModelSerializer
class InstitutionSerializer(serializers.ModelSerializer):
class Meta:
model = Institution
fields = ('name', 'dept')
class LeadSerializer(serializers.ModelSerializer):
class Meta:
model = Lead
fields = ('name_last', 'name_first', 'email', 'title')
class SiteSerializer(serializers.ModelSerializer):
class Meta:
model = Site
fields = ('name', 'lead')
class InvestigatorSerializer(WritableNestedModelSerializer, serializers.ModelSerializer):
institution = InstitutionSerializer
class Meta:
model = Investigator
fields = ('__all__')
depth = 1
datatables_always_serialize = ('id',)
class StudySerializer(WritableNestedModelSerializer, serializers.ModelSerializer):
investigator = InvestigatorSerializer()
site = SiteSerializer()
class Meta:
model = Study
fields = ('id', 'name_full', 'name_short', 'investigator', 'bhrrc_approval', 'start_date', 'end_date', 'enrollment_goal', 'current_enrollment', 'status', 'site',)
depth = 3
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 StudyView(viewsets.ModelViewSet):
queryset = Study.objects.all()
serializer_class = StudySerializer
class StudyList(generics.ListCreateAPIView):
queryset = Study.objects.all()
serializer_class = StudySerializer
class StudyDetail(generics.ListCreateAPIView):
queryset = Study.objects.all()
serializer_class = StudySerializer
class InvestigatorView(viewsets.ModelViewSet):
queryset = Investigator.objects.all()
serializer_class = InvestigatorSerializer
permission_classes = [AllowAny]
def perform_create(self, serializer):
serializer.save()
def perform_destroy(self, instance):
instance.delete()
class LeadView(viewsets.ModelViewSet):
queryset = Lead.objects.all()
serializer_class = LeadSerializer
class InstitutionView(viewsets.ModelViewSet):
queryset = Institution.objects.all()
serializer_class = InstitutionSerializer
class SiteView(viewsets.ModelViewSet):
queryset = Site.objects.all()
serializer_class = SiteSerializer