Search code examples
pythondjangodjango-rest-frameworkdjango-viewsdrf-queryset

Try, Except is not giving required result in django serializers create method. the getobject statements gives required result if put is outside try:


class BeneficiarySerializer(serializers.Serializer):
    class Meta:
        model = Beneficiary
        fields ='__all__'

    def create(self, validated_data):
        try:
            available = Beneficiary.objects.get(coupon_code=validated_data['coupan_code'])
            raise serializers.ValidationError("The provided coupon code is already utilized")
        except:
            return super().create(validated_data)


class Coupon(models.Model):
    sl_no = models.CharField(max_length=50, primary_key=True)
    c_code = models.CharField(max_length=50, blank=True)

    def __str__(self):
        return self.c_code


class Beneficiary(models.Model):
    name = models.CharField(max_length=50)
    coupon_code = models.ForeignKey(Coupon, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

purpose is to issue a coupon to only one person, if the same coupon code is issued to another in that case Serializers should raise and error that the key is issued to someone. if i put the code in try and except every time the verification fails, the same coupon code is allotted to many, if use objects.get outside try: statement is return result is found. please let me know if i am not using try: except in proper way or any other way to deal with this situation


Solution

  • The problem is no matter what that code is going to raise an exception and the call to super is going to occur any way. If there is no matching Beneficiary for your query a DoesNotExist exception will be raised by the get method, if it does you yourself raise an exception. Immediately you catch them and call super.

    Moving further you don't even need exceptions for this simple purpose, neither should you perform this validation in the create method! You should write a validate_<field> method and make an exists query there:

    class BeneficiarySerializer(serializers.Serializer):
        class Meta:
            model = Beneficiary
            fields ='__all__'
        
        def validate_coupon_code(self, value):
            if Beneficiary.objects.filter(coupon_code=value).exists():
                raise serializers.ValidationError("The provided coupon code is already utilized")
            return value