Reputation: 2000
I have a generic api view that I would like to use for both put, delete (and eventually, update) of records for a certain model, but I am fairly confused about the best practice for deleting a record in Django. Should I use the built-in delete method, or do I define my own? Do I process it as a DELETE or 'destroy' method on a GenericAPIView. I don't want to allow just anyone to delete a record, so I need to first validate that they are the same user that created the record. By some accounts, it sounds like Django allows you to delete a record with just authentication and the id. If true, how do I disable this behavior?
Thanks for any code or guidance on these various questions.
frontend.js
const deleteRow = (id) => {
alert(id)
fetch(`${SERVER_URL}/api/v1/requirements/related_files/${id}`, {
method: 'DELETE',
credentials: 'include',
headers: {
Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json',
Authorization: `Token ${token}`,
},
views.py
class CommentsView(GenericAPIView):
authentication_classes = (TokenAuthentication,)
serializer_class = CommentsSerializer
def post(self, request):
request.data['user'] = request.user.id
comment = CommentsSerializer(data=request.data)
if comment.is_valid():
comment.save()
return Response(comment.data, status=status.HTTP_201_CREATED)
return Response(comment.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self,request):
???? what do I do here ????
Upvotes: 0
Views: 6353
Reputation: 12090
Using built-in behavior is fine, just subclass rest_framework.viewsets.ModelViewSet
- this comes with all the usual create/update/delete functionality. If you want to protect deletion, the add your own permission class.
from rest_framework.permissions import BasePermission
class OnlyOwnerDeletePermission(BasePermission):
def has_object_permission(self, request, view, obj):
if request.method == "DELETE":
return request.user.id == obj.user_id # prevent fetching whole user model
return True # anyone can do any other action
Upvotes: 1
Reputation: 111
You can also make use of mixins, i.e, UpdateModelMixin and DestroyModelMixin alongside GenericViewSet.
class CommentsViewSet(UpdateModelMixin, DestroyModelMixin, GenericViewSet):
authentication_classes = (TokenAuthentication,)
serializer = CommentsSerializer
Model = Comments // Write your model name here
queryset = Comments.objects.all()
Then your urls will look like this, as you are using ViewSet you should use routers.
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'^requirements/related_files/', views.CommentsViewSet)
urlpatterns = {
path("/api/v1/", include(router.urls))
}
Upvotes: 1
Reputation: 1150
URL should include of object that you want delete it . we assume urls.py
is something like :
url(r'^/api/v1/requirements/related_files/(?P<comment_id>[0-9]+)/$', views.CommentsView.as_view())
and then in delete
part we just need have comment_id
:
class CommentsView(GenericAPIView):
authentication_classes = (TokenAuthentication,)
serializer_class = CommentsSerializer
def post(self, request):
request.data['user'] = request.user.id
comment = CommentsSerializer(data=request.data)
if comment.is_valid():
comment.save()
return Response(comment.data, status=status.HTTP_201_CREATED)
return Response(comment.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self,request):
comment_id = self.kwargs["comment_id"]
comment = get_object_or_404(Comment, id=comment_id)
comment.delete()
return Response(status=204)
Upvotes: 2