[Answered ]-I modify response.data in Django REST Framework view.py. Why am I getting an AttributeError during testing but not with actual API use?

1👍

You mean modifying request.data? I also got this error before.

Then I read Django documentation QueryDict, I think the "request.data":

  • is dictionary-like, not dictionary.

  • data type is immutable.

  • copy that before modifying, like:

     req_data = request.data.copy()
     req_data['submission_date'] = datetime.now()
    

And the reason of error not occurring during actual API use, maybe just the status not in these conditions.

On the other hand, in this case I usually set a modified_at or created_at DateTimeField in models.py, so that will record the submission_date automatically whenever the data is modified or created. I feel that is convenient.

created_at = models.DateTimeField(auto_now_add=True, help_text="submission_date")
modified_at = models.DateTimeField(auto_now=True, help_text="re-submission_date")

Edit for another possible solution by using ModelSerializer:

Purpose: We want to update the data not just based on request.data directly.
We want to use some other logic: if status == ‘submitted’ then…

And I suppose submission_date, packaged_date, finished_date are fields of Order Model.

views.py

def partial_update(self, request, pk, *args, **kwargs):
    order = Order.objects.get(id=pk)
    serializer = OrderSerializer(order, data=request.data, partial=True)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    else:
        return Response(serializer.errors)
    

serializers.py

class OrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

    def update(self, order, validated_data):
        status = validated_data.get('status')
        order.status = status
        if status == 'submitted':
            order.submission_date = datetime.now()
        elif status == 'packaged':
            order.packaged_date = datetime.now()
        elif status in ['sold', 'canceled', 'abandoned']:
            order.finished_date = datetime.now()

        order.save()
        return order

Leave a comment