2

I have a Django Rest Framework set up and I'd like to be able to send PATCH requests to it that update a specific field. I looked at some previous posts and incorporated the partial update code in my view:

class RequestViewSet(viewsets.ModelViewSet):
    queryset = Request.objects.filter(done = False).order_by('-time')
    serializer_class = RequestSerializer
    paginate_by = None

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)

When I try to run curl requests using PATCH, though, the object doesn't get updated. Here's an example of curl I was using:

curl --data '{"request": "foo"}' -X PATCH http://127.0.0.1:8000/api/request/1/

In the terminal, it returns the original, unmodified object. Is there a different way to set up the Model ViewSet to accept partial updates via PATCH?

hackerman
  • 1,221
  • 3
  • 17
  • 38
  • Have you read this? https://stackoverflow.com/questions/16306624/how-to-use-patch-verb-with-curl – Cory Madden Jul 24 '17 at 00:25
  • Yeah, that's actually where I got my curl format. I took it from Nick Brady's comment, though, because the top comment didn't seem to include a way to include the data. I tried adding it after the url and that threw up an error. – hackerman Jul 24 '17 at 00:27
  • What was the error and what was the command? It sounds like the problem is with your curl command. What kind of request does it say in the Django shell(where you're doing ./manage.py runserver) – Cory Madden Jul 24 '17 at 00:32
  • I think you were partially correct. I had a syntax error in the original curl that threw an error. With this `curl --request PATCH http://127.0.0.1:8000/api/request/1/?done=True`, it returns the original object without changing `done` to `true`. (I tried upper and lower case true, for what it's worth.) – hackerman Jul 24 '17 at 00:38
  • The curl command you show in your original post shows you trying to change `request` to `foo`. And are you unable to add a `--data` parameter to that curl command? `curl --request PATCH http://127.0.0.1:8000/api/request/1/ --data '{"done": "True"}'` – Cory Madden Jul 24 '17 at 00:49
  • Yes, adding the `--data` parameter doesn't seem to work. I copied and pasted your code into the terminal and it won't update the object. – hackerman Jul 24 '17 at 00:58
  • did you ever resolve this? I'm having exactly the same issue and I've tried changing the curl request in several ways with the same outcome; an unchanged object. – Hildy Nov 19 '18 at 03:12

2 Answers2

1

I commented on the OP before realizing how late to the party I was...but I did figure it out. It seems that the curl syntax for DRF is just a bit finicky.

After many experiments, I found that this works. (and yes, XPATCH is one word):

curl -XPATCH -H 'Content-Type:application/json' --data '{"request": "foo"}' \
http://127.0.0.1:8000/api/request/1/
Hildy
  • 510
  • 5
  • 15
  • Works fine. In case anyone's wondering, on Windows, you'd have to replace the double quotes with triple double quotes and the single quotes with double quotes. – Endre Both Jan 28 '19 at 13:33
  • @Endre - good info. I don't have a Windows machine, so I wouldn't have even thought of it. Thanks for posting! – Hildy Jan 29 '19 at 21:08
1

If you prefer not to mess with the content type stuff, you might find this to work (note that XPATCH is not needed):

curl -X PATCH --data 'published=True' \
    http://127.0.0.1:8000/api/rest/v3/visualizations/14/

Using the --data flag feels a bit cleaner on the command line, at least to me.

mlissner
  • 17,359
  • 18
  • 106
  • 169