英文:
Django declaring a read-only field on serializer
问题
我理解你的需求。你想要在GET请求中向用户显示主键id
,并且将其显示为orderId
,同时在创建订单时不要求用户提供orderId
,因为它应该在对象创建时自动生成。为了实现这一点,你可以使用以下代码:
class OrderSerializer(serializers.ModelSerializer):
orderId = serializers.UUIDField(source="id", read_only=True)
orderName = serializers.CharField(source="name")
class Meta:
model = Order
fields = (
"orderId",
"orderName",
)
这里,我们在orderId
字段上设置了read_only=True
,这意味着它在创建订单时不会被要求提供,但在GET请求中将显示。
这样,你的要求应该得到满足:
- 用户可以在GET请求中看到主键
id
,显示为orderId
。 - 创建订单时,不需要用户提供
orderId
,因为它会自动生成。
英文:
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...
- visible to the user in a GET request
- visible to the user under the name
orderId
- not a required field when generating an order, since it should be automatically created like most Primary Keys are
答案1
得分: 1
你应该指定 read_only=True
来将字段标记为只读。通过自定义它,你阻止了Django自行完成这个操作:
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',)
英文:
You should specify read_only=True
to mark the field as readonly. By customizing it yourself, you prevented Django from doing this itself:
<pre><code>class OrderSerializer(serializers.ModelSerializer):
orderId = serializers.UUIDField(source='id'<b>, read_only=True</b>)
orderName = serializers.CharField(source='name')
class Meta:
model = Order
fields = (
'orderId',
'orderName',
)
read_only_fields = ('orderId',)</code></pre>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论