I have an endpoint that needs to expose the fields to the user, but under a different name. The user should -not- be able to set the PK (called orderId
here) when creating the object, since that should be done automatically with a randomly set value when the object is created.
Here is my serializer.
class OrderSerializer(serializers.ModelSerializer):
orderId = serializers.UUIDField(source="id")
orderName = serializers.CharField(source="name")
class Meta:
model = Order
fields = (
"orderId",
"orderName",
)
read_only_fields = ("orderId",)
Here is my model:
class Order(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=48)
Note that id
in the model is exposed to the user under the name orderId
.
The problem is this set up seems to make it a required field when when a user creates an order. With the above set up, a POST request setting just orderName
in the body to create an order gives this error:
{
"orderId": [
"This field is required."
]
}
Unless of course the user sends a value for orderId
, which they should not do.
I had hoped including the "orderId" as a ready only field would make it not required in a POST request, but that does not seem to be the case. Obviously the field needs to be required in the DB, but it should not be required in a POST request.
If I remove the orderId
from fields, I get:
The field 'messageId' was declared on serializer OrderSerializer, but has not been included in the 'fields' option.
And if I remove if from the serialize entirely (remove orderId = serializers.UUIDField(source="id")
) then I can create an Order but the id does not show up in a GET request, where I need it to be seen.
How can I make it so that the order's primary key id
is...
orderId
You should specify read_only=True
to mark the field as readonly. By customizing it yourself, you prevented Django from doing this itself:
class OrderSerializer(serializers.ModelSerializer):
orderId = serializers.UUIDField(source='id', read_only=True)
orderName = serializers.CharField(source='name')
class Meta:
model = Order
fields = (
'orderId',
'orderName',
)
read_only_fields = ('orderId',)