ambe5960
ambe5960

Reputation: 2000

Delete/destroy method in django

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

Answers (3)

Anonymous
Anonymous

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

HabibUllah Khan
HabibUllah Khan

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

mehdi
mehdi

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

Related Questions