验证序列化器中的几个json对象,并返回所有json对象django [英] Validate only few json objects in serializers and return all json objects django

查看:98
本文介绍了验证序列化器中的几个json对象,并返回所有json对象django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的序列化文件

 来自rest_framework导入序列化器

#此处所有验证
类BudgetSerializer (serializers.Serializer):
start_date = serializers.DateTimeField(format =%Y-%m-%d%H:%M:%S)
end_date = serializers.DateTimeField(format = %Y-%m-%d%H:%M:%S)
lifetime_budget =序列化器。FloatField(max_value = None,min_value = None,allow_null = True)

def validate(self,attrs):
如果attrs ['start_date']> attrs ['end_date']:
引发serializers.ValidationError( start_date必须小于结束日期)
返回attrs
类IoSerializer(serializers.Serializer):
名称= serializers.CharField()
状态= serializers.CharField()
货币= serializers.CharField(read_only = True)
budget_type = serializers.CharField(read_only = True)
budget_intervals = BudgetSerializer(很多=真)

我要序列化的Json有1000个字段,但我只想验证几个字段并返回所有json字段。但是serialzer的问题是它只输出由serializer中提到的字段组成的json。


就像我要发送带有1000个对象名的json一样,但是返回由start_date,end_date,lifetime_budget,name组成的json,因为它在序列化器文件中提到。我只想验证几个字段,所以我将它们写在序列化器文件中,但仅此字段会返回。


我的views.py代码

  class InsertionOrderViewset(viewsets.ViewSet):

def create(self,request,format = None):
advertiser_id = request.query_params.get('advertiser_id',None)
data = json.dumps(request.data)
io_object = json.loads(数据,object_hook = lambda x:namedtuple('io_object',x.keys())(* x.values()))
serializer = IoSerializer(data = request。 data,instance = io_object)
serializer.is_valid(raise_exception = True)
response_data = IO.create(data = request.data,params = { advertiser_id:Advertiser_id})
返回响应(request.data)


解决方案

serializers.data 方法将仅返回提供给它的值,除非您声明了某些 read_only 字段或执行以下任何操作-提供一个实例在序列化程序初始化期间,从<$ c返回一个实例$ c> serializer.save 方法。如果 serializer.instance 有一个值,则 read_only 字段将返回 serializer.data 。您的用例建议传入的JSON对象具有数千个数据,其中只有一小部分需要验证。我的建议是不要传递所有数据,仅摘录数据的必要部分,将它们发送给序列化器并进行验证,如果有任何其他重新加入,则返回 serializer.errors serializer.data 与传入的JSON并返回JSON。由于大多数数据与验证无关,由于 drf-serializer 验证和映射值的方式,将它们传递给序列化器将导致严重的性能问题。 / p>

如果仍然要向序列化器提供所有JSON并仅验证少数几个,请考虑在初始化序列化器时考虑提供实例,动态声明 ReadOnlyField 在您的 serializer中。__init __


serializers.py

 来自rest_framework导入序列化程序

#对象的默认属性
default_attrs = ['__doc__ ','__ module __','__ slots __','_ fields','_ source']

class BudgetSerializer(serializers.Serializer):
start_date = serializers.DateTimeField(format =''%Y -%m-%d%H:%M:%S)
end_date =序列化器。DateTimeField(format =%Y-%m-%d%H:%M:%S)
lifetime_budget = serializers.FloatField(ma x_value = None,min_value = None,allow_null = True)

def __init __(self,* args,** kwargs):
super(BudgetSerializer,self).__ init __(* args,* * kwargs)
实例= kwargs.get('instance',None)dir(instance)中attr的
:如果attr不在self.fields中且不可调用(getattr(instance, attr))和attr不在default_attrs中:
self.fields [attr] = serializers.ReadOnlyField()

def validate(self,attrs):
如果attrs ['start_date ']> attrs ['end_date']:
提高serializers.ValidationError( start_date必须小于结束日期)
返回attrs


类IoSerializer(serializers。序列化器):
名称= serializers.CharField()
状态= serializers.CharField()
货币= serializers.CharField(read_only = True)
budget_type = serializers.CharField(read_only = True)
budget_intervals = BudgetSerializer(很多= True)

def __init __(self,* args,** kwargs):
super(IoSerializer,self).__ init __(* args,** kwargs)
instance = kwargs.get('instance',None)dir(instance)中attr的
:如果attr不在self.fields中且不可调用(getattr),则
(实例,attr))和attr不在default_attrs中:
self.fields [attr] = serializers.ReadOnlyField()

内部 views.py

 导入js在
上从集合中导入namedtuple

#内部视图
data = json.dumps(request.data)
io_object = json.loads(data,object_hook = lamdba x :namedtuple('io_object',x.keys())(* x.values()))
serializer = IoSerializer(data = request.data,instance = io_object)
serializer.is_valid(raise_exception = True)
print(serializer.data)


This is my serializer file

from rest_framework import serializers

#All validations here
class BudgetSerializer(serializers.Serializer):
    start_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    end_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    lifetime_budget = serializers.FloatField(max_value=None, min_value=None,allow_null=True)

    def validate(self, attrs):
        if attrs['start_date'] > attrs['end_date']:
            raise serializers.ValidationError("start_date must be less than end date")
        return attrs  
class IoSerializer(serializers.Serializer):
        name  =  serializers.CharField()
        state =  serializers.CharField()
        currency = serializers.CharField(read_only=True)
        budget_type = serializers.CharField(read_only=True)
        budget_intervals = BudgetSerializer(many=True)

Json which i am serializing has 1000's of fields but i only want to validate few fields and return all json fields.But problem with serialzer is that it only outputs json consisting of mentioned field in serialiser.

Like i am sending json with 1000s of object names but it only return json which consist of start_date,end_date,lifetime_budget,name because it is mentioned in serializer file.I wanted to only validate few fields so i wrote them in serializer file but only this fields are returned.

My views.py code

class InsertionOrderViewset(viewsets.ViewSet):

    def create(self, request, format=None):
        advertiser_id = request.query_params.get('advertiser_id', None)
        data = json.dumps(request.data) 
        io_object = json.loads(data, object_hook=lambda x: namedtuple('io_object', x.keys())(*x.values()))
        serializer = IoSerializer(data=request.data, instance=io_object)
        serializer.is_valid(raise_exception=True) 
        response_data = IO.create(data=request.data, params={"advertiser_id": advertiser_id })
        return Response(request.data)

解决方案

serializers.data method will only return values which are supplied to it unless you declare some read_only fields and or do any of these - supply an instance during serializer initialization, return an instance from serializer.save method. When serializer.instance has a value then read_only fields are returned with serializer.data. Your use case suggests that the incoming JSON object has 1000s of data of which only a small portion requires validation. My suggestion will be not to pass all the data, pluck only the necessary portion of the data, send them to serializer and do validation, return serializer.errors if any else rejoin the serializer.data with the incoming JSON and return the JSON. Since, majority of the data has nothing to do with validation, passing them in to the serializer will cause significant performance issue due to the way drf-serializer validates and maps values.

Still if you still want to supply all of the JSON to serializer and validate only a few consider supplying an instance when initializing serializer, dynamically declare ReadOnlyField in your serializer.__init__

serializers.py

from rest_framework import serializers

# default attributes of objects
default_attrs = ['__doc__', '__module__', '__slots__', '_fields', '_source'] 

class BudgetSerializer(serializers.Serializer):
    start_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    end_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S")
    lifetime_budget = serializers.FloatField(max_value=None, min_value=None,allow_null=True)

    def __init__(self, *args, **kwargs):
        super(BudgetSerializer, self).__init__(*args, **kwargs)
        instance = kwargs.get('instance', None)
        for attr in dir(instance):
            if attr not in self.fields and not callable(getattr(instance, attr)) and attr not in default_attrs:
                self.fields[attr] = serializers.ReadOnlyField()

    def validate(self, attrs):
        if attrs['start_date'] > attrs['end_date']:
            raise serializers.ValidationError("start_date must be less than end date")
        return attrs
    

class IoSerializer(serializers.Serializer):
    name  =  serializers.CharField()
    state =  serializers.CharField()
    currency = serializers.CharField(read_only=True)
    budget_type = serializers.CharField(read_only=True)
    budget_intervals = BudgetSerializer(many=True)
    
    def __init__(self, *args, **kwargs):
        super(IoSerializer, self).__init__(*args, **kwargs)
        instance = kwargs.get('instance', None)
        for attr in dir(instance):
            if attr not in self.fields and not callable(getattr(instance, attr)) and attr not in default_attrs:
                self.fields[attr] = serializers.ReadOnlyField()

inside views.py

import json
from collections import namedtuple

# inside view
data = json.dumps(request.data) 
io_object = json.loads(data, object_hook=lamdba x: namedtuple('io_object', x.keys())(*x.values()))
serializer = IoSerializer(data=request.data, instance=io_object)
serializer.is_valid(raise_exception=True) 
print(serializer.data)

这篇关于验证序列化器中的几个json对象,并返回所有json对象django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆