python-3.x 将所有序列化程序字段设置为必填字段

42fyovps  于 2023-02-26  发布在  Python
关注(0)|答案(4)|浏览(107)

我有下一个序列化器:

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字段,但事实并非如此
当我在Client list API视图中选中 options 时,我得到的地址如下:

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

但是当我检查Address list 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参数的情况下将所有字段设置为必填?

jmo0nnb3

jmo0nnb31#

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

以上内容摘自DRF 3.1.2源代码,显示了如何确定自动生成的串行器字段ModelSerializerrequired属性。
您所观察到的是设计的结果,如果您希望自动生成的序列化程序字段具有required = True属性,则其对应的模型字段必须既不具有默认值,也不接受空白或空值。

fzwojiic

fzwojiic2#

有默认值的字段不是必输项,需要明确标记为必输项:

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
rkue9o1l

rkue9o1l3#

还有一种方法可能比覆盖get_fields更简洁:
我通过提供extra_kwargs解决了一个类似的问题(将可选字段标记为必填字段),或者,如果您需要更动态的东西,可以覆盖序列化器上的get_extra_kwargs方法。

pbwdgjma

pbwdgjma4#

如果你需要在某些领域这样做,这对我很有效:

some_field = serializers.PrimaryKeyRelatedField(
    queryset=YourModel.objects.all(),
    allow_null=False,
    allow_empty=False,
    required=True
)

def validate_some_field(self, value):
    if value is None:
        raise serializers.ValidationError("Required.")
    return value

相关问题