我有一个这样的模型:
class Things(models.Model):
data = models.JSONField(default=dict)
CCD_ 1的结构如下:
{
"item" : "sugar",
"quantity" : "2",
"cost" : 220
}
请注意,data
不必包含所有3个密钥,它们都是可选的。
困难的部分是,除了这3个键之外,我不希望任何其他键出现在data
字段中。
创建序列化程序可以帮助确保这3个字段的存在和格式,但不能确保没有其他字段。如何在django-rest框架中实现这一点?
您可以验证序列化程序中的字段:
class ThingsSerializer(serializers.ModelSerializer):
class Meta:
model = Things
fields = ['data']
def validate_data(self, value):
# You can validate, clean and change your data
final_data = {
"item": value.get("item"),
"quantity": value.get("quantity"),
"cost": value.get("cost", 0)
}
return final_data
您还可以为数据字段创建一个单独的序列化程序,并将值传递给它,验证那里的每个字段并返回最终数据。但是,如果你的领域是有限的和简单的,这应该做。
通过在序列化程序级别中使用validate_<field_name>
,您还可以创建一个逻辑来确保data
中的所有字段都需要填充。
class ThingsSerializer(serializers.ModelSerializer):
data = serializers.JSONField()
class Meta:
model = Things
fields = ('data', )
def validate_data(self, data):
valid_keys = ('item', 'quantity', 'cost')
errors = []
out_data = {}
for key in valid_keys:
if key in data.keys():
if data.get(key):
out_data[key] = data.get(key)
else:
errors.append({key: 'This field should be filled.'})
else:
errors.append({key: 'This field is required'})
if len(errors) > 0:
raise serializers.ValidationError(errors)
return out_data
以下是测试:
In [25]: s = ThingsSerializer(data={'data': {'item': 'sugar', 'quantity': 2, 'cost': 20}})
In [26]: s.is_valid()
Out[26]: True
In [27]: s.errors
Out[27]: {}
In [28]: s = ThingsSerializer(data={'data': {'item': 'sugar', 'quantity': 2}})
In [29]: s.is_valid()
Out[29]: False
In [30]: s.errors
Out[30]: {'data': [{'cost': ErrorDetail(string='This field is required', code='invalid')}]}
In [34]: s = ThingsSerializer(data={'data': {'item': 'sugar', 'quantity': 2, 'cost': None}})
In [35]: s.is_valid()
Out[35]: False
In [36]: s.errors
Out[36]: {'data': [{'cost': ErrorDetail(string='This field should be filled.', code='invalid')}]}