简体   繁体   English

序列化器不可序列化数据的全部捕获字段

[英]Catch-all field for unserialisable data of serializer

I have a route where meta-data can be POSTed.我有一条可以发布元数据的路线。 If known fields are POSTed, I would like to store them in a structured manner in my DB, only storing unknown fields or fields that fail validation in a JSONField .如果发布了已知字段,我想以结构化方式将它们存储在我的数据库中,只存储未知字段或在JSONField中验证失败的字段。

Let's assume my model to be:假设我的 model 是:

# models.py
from django.db import models


class MetaData(models.Model):
  shipping_address_zip_code = models.CharField(max_length=5, blank=True, null=True)
  ...
  unparseable_info = models.JSONField(blank=True, null=True)

I would like to use the built-in serialisation logic to validate whether a zip_code is valid (5 letters or less).我想使用内置的序列化逻辑来验证zip_code是否有效(5 个字母或更少)。 If it is, I would proceed normally and store it in the shipping_address_zip_code field.如果是,我会正常进行并将其存储在shipping_address_zip_code字段中。 If it fails validation however, I would like to store it as a key-value-pair in the unparseable_info field and still return a success message to the client calling the route.但是,如果验证失败,我想将其作为键值对存储在unparseable_info字段中,并仍然向调用该路由的客户端返回一条成功消息。

I have many more fields and am looking for a generic solution, but only including one field here probably helps in illustrating my problem.我有更多的领域,正在寻找一个通用的解决方案,但这里只包括一个领域可能有助于说明我的问题。

 def validate_shipping_address_zip_code(self, value):
      if value >= 5:
        return value
      else:
          raise serializers.ValidationError("Message Here")

there's much more validators in serializer look into more detail https://www.django-rest-framework.org/api-guide/serializers/序列化器中有更多的验证器查看更多细节https://www.django-rest-framework.org/api-guide/serializers/

from rest_framework import serializers
class MetaDataSerializer(serializers.ModelSerializer):
    unparseable_info = serializers.JSONField(required=False)
    class Meta:
        model = MetaData
        fields = ('shipping_address_zip_code', 'unparseable_info')
    
    def validate_shipping_address_zip_code(self, value):
        if len(value) > 5:
            raise serializers.ValidationError("Zip code is too long")
        return value
    
    def create(self, validated_data):
        unparseable_info = {}
        for key, value in self.initial_data.items():
            try:
                validated_data[key] = self.fields[key].run_validation(value)
            except serializers.ValidationError as exc:
                unparseable_info[key] = value
                validated_data.pop(key, None)
    
        instance = MetaData.objects.create(**validated_data)
    
        if unparseable_info:
            instance.unparseable_info = unparseable_info
            instance.save()
    
        return instance

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM