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

Back to Top