将所有序列化程序字段设置为必需

Setting all serializer fields to be required

我有下一个序列化程序:

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address

class ClientSerializer(serializers.ModelSerializer):
  address = AddressSerializer()
  class Meta:
    model = Client
    fields = ('id', 'email', 'address')

模特:

class Address(models.Model):
    street = models.CharField(max_length=50, default='')
    zip = models.CharField(max_length=5, default='')
    state = models.CharField(max_length=50, choices=STATES ,default='')
    suburb = models.CharField(max_length=50, default='')
    num = models.CharField(max_length=7, blank=True, default='')
    country = models.CharField(max_length=50, default='')
    ref = models.CharField(max_length=120, blank=True)

class Client(models.Model):
    address = models.OneToOneField(Address, null=True)
    email = models.EmailField(unique=True, default='')

预期的行为是根据需要拥有所有 AddressSerializer 字段,但事实并非如此

当我检查客户端列表 api 视图中的 选项 时,我得到的地址是这样的:

"address": {
    "type": "field",
    "required": true,
    "read_only": false,
    "label": "Address"
}

但是当我查看地址列表时 api 查看我的所有字段都是可选的:

"street": {
    "type": "string",
    "required": false,
    "read_only": false,
    "label": "Street",
    "max_length": 50
},
"state": {
    "type": "string",
    "required": false,
    "read_only": false,
    "label": "State",
    "max_length": 50
},
"zip": {
    "type": "string",
    "required": false,
    "read_only": false,
    "label": "ZIP",
    "max_length": 5
},

为什么应该是必填字段却不是?

如何在不使用 extra_kwargs 参数的情况下将所有字段设置为必填项?

if model_field.has_default() or model_field.blank or model_field.null:
    kwargs['required'] = False

以上是 DRF 3.1.2 源代码的摘录,展示了如何确定 ModelSerializer 的自动生成的序列化程序字段的 required 属性。

您所观察到的是设计使然。如果你想让一个自动生成的序列化器字段有required = True属性,它对应的模型字段不能有默认值,不能接受空白,也不能接受空值。

不需要具有默认值的字段。您需要明确地将它们标记为必需:

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address

    def get_fields(self):
        fields = super(AddressSerializer, self).get_fields()
        for field in fields.values():
            field.required = True
        return fields

有另一种方法可能被认为比重写 get_fields:

更干净

我通过提供 extra_kwargs 解决了一个类似的问题(根据需要标记可选字段)。或者,如果您想要更动态的东西,您可以覆盖序列化程序上的 get_extra_kwargs 方法。