Search code examples
djangodjango-modelsdjango-rest-frameworkbackenddjango-serializer

How do I add a default value to a nested serializer?


I am trying to have my "address" API return the default value (empty string ""), but when I use default="" in the serializer field it returns null instead. This is my main serializer (LocationSerializer)


class LocationSerializer(serializers.ModelSerializer):
    id = serializers.UUIDField(read_only=True)
    business_id = serializers.PKRelatedField(Business.any.all(), "business")
    city_id = serializers.UUIDField(required=True)
    name = serializers.CharField(max_length=48, required=True)
    tax_number = serializers.CharField(max_length=48)
    phone = serializers.PhoneNumberField()
    address = serializers.CharField()
    address_details = AddressEmbeddedSerializer(default="", source="addresses")
    footer = serializers.CharField()
    is_active = serializers.BooleanField(required=True)
    has_kds = serializers.BooleanField(read_only=True)
    position = serializers.PointField()
    image = serializers.ImageField()
    # profile = LocationProfileSerializer()
    permissions = PermissionSerializer(many=True, read_only=True)
    payment_methods = PaymentMethodEmbeddedSerializer(many=True, read_only=True)

    class Meta:
        model = Location
        fields = (
            "id", "business_id", "city_id", "name", "tax_number", "phone", "address", "address_details", "footer",
            "is_active", "has_kds", "position", "image", "permissions", "payment_methods"
        )

and this is my nested serializer (AddressEmbeddedSerializer)



class AddressEmbeddedSerializer(serializers.ModelSerializer):
    city = serializers.CharField(default="")
    area = serializers.CharField(default="")
    block = serializers.CharField(default="")
    avenue = serializers.CharField(default="")
    long = serializers.CharField(default="")
    lat = serializers.CharField(default="")

    class Meta:
        model = LocationAddress
        fields = (
            "city", "area", "block", "avenue", "long", "lat"
        )

The value that I am expecting is:

"address_details": {
            "city": "",
            "area": "",
            "block": "",
            "avenue": "",
            "long": "",
            "lat": ""
        }

Instead what I am getting is:

"address_details": null

Please note that all CRUD operations are working, this is only a default value issue


Solution

  • The reason why "address_details": null is that the current object has no related addresses at a model object so the nested serializer won't be accessed and therefore your desired JSON output won't be generated.

    Also, default is used when no value provided for the field with POST request not GET

    I suggest that you handle address_details when it is null, but if you really need to do this you can do something at to_representation() or to_internal_value(), see this answer: https://stackoverflow.com/a/38606711/4984493

    Also, you can use SerializerMethodField, so based on obj.addresses's value if it was null or not you return the desired JSON output you need.