John
John

Reputation: 299

one to one field update serialization issue

###################### Requirement #############################

/add_value/

payload: { "profile_id": "34AB", "amt": 100.00 }

###################### Viewset ####################################

class cash_viewset(ModelViewSet):

queryset = Cashbalance.objects.all()
serializer_class = SampleSerializer

####################### Models ####################################

MOdel -1 ---

class Profile(models.Model):

user = models.OneToOneField(User, on_delete=models.CASCADE)
profile_id = models.CharField(max_length=50,unique=True)

MOdel -2 ---

class Cashbalance(models.Model):

profile = models.OneToOneField(Profile, on_delete=models.CASCADE,db_column="profile_id")
remianingAmount = models.FloatField()
amt = models.FloatField()

############################### Serializer ##############################

class SampleSerializer(serializers.ModelSerializer):

profile_id = serializers.CharField(source="profile.profile_id")
remianingAmount = serializers.FloatField(read_only=True)

class Meta:
    model = CashBalance
    fields = ["profile_id", "amt", "remianingAmount"]

def create(self, validated_data):
    profile_dict = validated_data['profile']
    userprofile = Profile.objects.get(profile_id=profile_dict['profile_id'])
    bank_obj = CashBalance.objects.filter(profile_id=userprofile)
    bank_obj.update(amt=validated_data['amt'], remianingAmount=validated_data['amt'])
    return bank_obj[0]

def to_representation(self, instance):
    data = super(serializers.ModelSerializer, self).to_representation(instance)
    print(instance.profile.user.username)
    result = {"profile_id": data['profile_id'], "name": instance.profile.user.username,
              "remianingAmount": data['remianingAmount']}
    return result

################################# Question is ######################

Assume that, there is already some data in user,profile and Cashbalance tables

As per the payload given above,Based on the profile_id ,I have to update amt value to 100, for this I have implemented the solution in create method(create method given above), please share your inputs ,I am hoping that update cannot be done in create method, how can i improve this in more good way according to my model designs by using modelviewset

Upvotes: 0

Views: 208

Answers (1)

umair
umair

Reputation: 534

To perform the update, you have to override the update method in the serializer.

def update(self, instance, validated_data):
  instance.profile.profile_id 
 = validated_data["profile"].get('profile_id',instance.profile.profile_id)
  instance.amt = validated_data.get('amt', instance.amt) 
  return instance

in your viewset

def update(self,request,pk=None):
   profile_id = request.data.get("profile_id")
   profile = Profile.objects.get(profile_id = profile_id)
   ser = self.get_serializer_class()(instance=profile.cash_balance , data = request.data)
   ser.is_valid(raise_exception=True)
   ser.save()

in your CashBalanceModel, pass a related_name

profile = models.OneToOneField(Profile, on_delete=models.CASCADE,db_column="profile_id" , related_name="cash_balance")

check docs: https://www.django-rest-framework.org/api-guide/serializers/

Upvotes: 0

Related Questions