4

I just got started with Django and got stuck on something that I believe should be simple, but I don't know how to do.

I have a model like this one:

id = models.AutoField(primary_key=true)
...
amount = models.IntegerField()
...

Basically, the user will give an amount and the model needs to be updated with the current amount + the amount that the user inputs.

I use serializers to create new objects, but I don't really know how to use them to do this.

ragtime.sp
  • 121
  • 1
  • 2
  • 11

2 Answers2

13

Let's assume the following:

  1. your model is called MyModel
  2. your serializer class is named MyModelSerializer
  3. AmountPartialUpdateView is extending APIView
  4. your partial update url is defined like this -that is, model id is passed in the pk URL variable and the amount to add is passed in the amount URL variable:

    urlpatterns = patterns('',
        # ...
        url(r'^model/update-partial/(?P<pk>\d+)/(?P<amount>\d+)$', AmountPartialUpdateView.as_view(), name='amount_partial_update'),
        # ...
    )
    

Then, you should implement the correct update logic in the AmountPartialUpdateView.patch() method. One way to accomplish this is:

from django.shortcuts import get_object_or_404
from rest_framework import Response


class AmountPartialUpdateView(APIView):

    def patch(self, request, pk, amount):
        # if no model exists by this PK, raise a 404 error
        model = get_object_or_404(MyModel, pk=pk)
        # this is the only field we want to update
        data = {"amount": model.amount + int(amount)}
        serializer = MyModelSerializer(model, data=data, partial=True)

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        # return a meaningful error response
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

This way, visiting the URL

model/update-partial/123/5

you will increase the amount of model id 123 by 5 units.

Paolo Stefan
  • 10,112
  • 5
  • 45
  • 64
  • How should be the URL I need to send the request to: whatever/model/update-partial/pk=1&amount=10 ? I am getting an 404 error on every combination I tried, and I know there is an object with that pk – ragtime.sp May 02 '18 at 09:21
  • Right, it does something now. I get an error unsupported operand types for +: int and str. Both model.amount and amount are int, so I don't get why is it complaining about that. – ragtime.sp May 02 '18 at 09:31
  • No, it's right: the `amount` in the URL segment is passed as a stirng to the patch() function - upated the answer again. – Paolo Stefan May 02 '18 at 09:33
  • OK, now I just need to create the update method in the serializer then. Let me try. – ragtime.sp May 02 '18 at 09:43
  • `def update(self, instance, validated_data): instance.amount = validated_data['amount'] instance.save() return instance` Shouldn't this work? I am getting an error simply saying KeyError amount – ragtime.sp May 02 '18 at 09:59
  • It's not mandatory: if your MyModelSerializer extends rest_framework.serializers.ModelSerializer, then my code will suffice without needing to override the serializer's update() method. – Paolo Stefan May 02 '18 at 10:01
  • 1
    Yep, that made the trick. Thank you so much! You are a life saver! – ragtime.sp May 02 '18 at 10:05
4

just use the partial=True as one of your serializer parameter and create an object for your filed that you want to update i.e i want to update the queue status

    data = {'queue_status': 1}
serializer_patient_queue = PatientQueueSaveSerializer(queue_item, data=data, partial=True)
Abednego
  • 599
  • 10
  • 17