I am experiencing some strange behaviour using the .save(field = 'value') on the perform_update event using Django Rest Framework inside view.py. I am updating a specific field, adding logic and adding additional data to the serializer before saving data in the model/database based on a the customer's response/api call.
Each time I test by setting a PUT (update) as 'yes' and then 'no', the .save() randomly works. I think sometimes the save() happens before the variable gets set and passed to .save(). I am fairly new to Django and Python so I may not be doing this correctly.
I have also tried declaring variables and then passing those variables into .save(field='created variable') but I still get the same strange behaviour.
Here is my code:
def perform_update(self, serializer):
# Change depending on customer's repsonse.
# customer_acceptance is "yes" or "no" from front end
print(serializer.instance.customer_acceptance)
if serializer.instance.customer_acceptance == 'yes':
serializer.instance.creditor_status = 'accepted'
serializer.instance.agreement_acceptance = 'yes'
if serializer.instance.customer_acceptance == 'no':
serializer.instance.creditor_status = 'customer_rejected'
serializer.instance.agreement_acceptance = 'no'
if serializer.is_valid():
print(serializer.instance.creditor_status)
serializer.save(
customer_response_date = datetime.datetime.now()
)
use this:
def perform_update(self, serializer):
obj = serializer.instance
obj.agreement_acceptance = obj.customer_acceptance
if obj.customer_acceptance == 'yes':
obj.creditor_status = 'accepted'
else
obj.creditor_status = 'customer_rejected'
serializer.save(customer_response_date = datetime.datetime.now())
don't need to call is_valid. it has already been called.
OK I think I have worked it out.
serializer.instance = as the data model is now before save, so it is always retrieving the data before save (not from the data in the PUT request). This is why it had strange behaviour each time I was saving yes then no, it would wait for the next api call to put the correct answer in.
I am now using validated_data["customer_acceptance"] == 'yes' in the serializer.py as below and it is working perfectly. Because it is based on the actual PUT call request data and not what it is currently in the instance/model:
def update(self, instance, validated_data):
# print(validated_data.get('customer_acceptance', instance.customer_acceptance))
# print(validated_data["customer_acceptance"])
# print(validated_data.get('customer_acceptance'))
if validated_data["customer_acceptance"] == 'yes':
instance.creditor_status = 'accepted'
instance.agreement_acceptance = 'yes'
if validated_data["customer_acceptance"] == 'no':
instance.creditor_status = 'customer_rejected'
instance.agreement_acceptance = 'no'
instance.customer_acceptance = validated_data.get('customer_acceptance', instance.customer_acceptance)
instance.customer_response_date = datetime.datetime.now()
instance.save()
return instance
I am not actually sure what the difference between these three things but they seem to derive the same answer:
print(validated_data.get('customer_acceptance', instance.customer_acceptance))
print(validated_data["customer_acceptance"])
print(validated_data.get('customer_acceptance'))