Django在序列化器上声明只读字段

huangapple go评论51阅读模式
英文:

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 = (
        &#39;orderId&#39;,
        &#39;orderName&#39;,
    )
    read_only_fields = (&#39;orderId&#39;,)&lt;/code&gt;&lt;/pre&gt;

huangapple
  • 本文由 发表于 2023年4月11日 04:15:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/75980386.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定