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

时间:2015-07-08 06:37:27

标签: django python-3.x django-rest-framework

我有下一个序列化器:

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参数的情况下优先设置所有字段?

3 个答案:

答案 0 :(得分:2)

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

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

您所观察到的是设计。如果希望自动生成的序列化程序字段具有required = True属性,则其对应的模型字段既不能具有默认值,也不能接受空白,也不能接受空。

答案 1 :(得分:2)

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

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

答案 2 :(得分:0)

另一种方法可能被认为比覆盖notMatched = re.sub(regex, "", string)更清晰:

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