【问题标题】:Setting all serializer fields to be required将所有序列化程序字段设置为必需
【发布时间】:2015-09-25 22:07:06
【问题描述】:

我有下一个序列化程序:

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 视图中检查 options 时,我得到的地址如下:

"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 参数的情况下将所有字段设置为最好?

【问题讨论】:

  • 您可以在模型上设置必填字段吗?
  • @jvc26 他们是,我只对其中一些使用blank=True
  • 你能发布你的模型吗,因为 ModelSerializer 提供的信息有限并且基于此

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


【解决方案1】:
if model_field.has_default() or model_field.blank or model_field.null:
    kwargs['required'] = False

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

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

【讨论】:

    【解决方案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
    

    【讨论】:

    • 虽然调用了这个函数,但是在这里设置 field.required 对我来说没有任何区别。我必须在序列化程序设置 required=True 中明确定义每个字段。我尝试在 init 函数中做同样的事情,但这也不起作用
    【解决方案3】:

    还有另一种可能被认为比覆盖 get_fields 更简洁的方法:

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

    【讨论】:

      猜你喜欢
      • 2022-01-22
      • 2013-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多