Serialization assembly |
django comes with the sequence of components but uncontrollable not recommended (to know)
from django.core Import serializers class Books (APIView): DEF GET (Self, Request): Response = { ' code ' : 100, ' MSG ' : ' successful query ' } Books = models.Book.objects.all () # Learn django comes serialization component RET = serializers.serialize ( " JSON " , Books) return the HttpResponse (RET)
Using the serialization component drf
Custom py file in order to view the function to isolate and view files in write custom serializer components
A new class inherits a sequence Serializer 2 write sequence of the fields in the class
source = 'field in the table' custom fields can not be field names of the table as
source value passed to the default parameter instance view function can not write the instance
source can be written across the table fields 'publish.name' across the table before book.publish.name is now a source you can write a book publish.name omitted
Not only you can specify a source field can specify a further method
# Custom py file from rest_framework Import serializers # serialization component class BookSerializer (serializers.Serializer): # Specify source = 'name' field represents the name of the table model serialization rename name5 (name5 field name and source = 'name' name field name specified in the model table is not the same) NAME5 = serializers.CharField (= Source ' name ' ) # WRITE_ONLY is serialized, this field does not show the distal end # READ_ONLY deserialization time, the field does not pass pass over the front when you can not pass parameters or fields . price = serializers.CharField (WRITE_ONLY = True) # across tables if you want to take the city before publishing queries are now book.publish.city source = 'publish.city' do not need click on the field itself in this form of the # value of the source parameter passed to the default instance = serializers.CharField publish (Source = ' publish.name ' ) # Press name # Source can not only specify a field, the method can also specify a custom field value is fixed choices get_ usage field _display book_type serializers.CharField = ( = Source ' get_category_display ' , READ_ONLY = True)
#model.py模型表 class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) category = models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1,null=True) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True) authors = models.ManyToManyField(to='Author') def __str__(self): return self.name def test(self): return '方法'
Using the sequence of the view class
Examples of the sequence of the class of the object is generated, when the object is generated, the incoming serialized objects required (QuerySet)
Object .data
return Response (Object .data) returns the value returned by Response
If the sequence of multiple = True MANY (ie queryset object, you need to write) If the sequence of a (can not write) instance to serialize objects
from app01.app01serializer Import BookSerializer # custom serialization assembly defined in document py from rest_framework.response Import the Response # returned with class Books (APIView): DEF GET (Self, Request): Response = { ' code ' : 100, ' msg ' : ' query success ' } Books = models.Book.objects.all () bookser = BookSerializer (instance = Books, MANY = True) # If the sequence of multiple, many = True (ie queryset object, need write) print(bookser.data,type(bookser.data)) response['data'] = bookser.data return Response(response)
Advanced Usage: SerializerMethodField with the method (get_ field names) write_only deserialize when the front end of the field is not displayed read_only deserialization when the front end can not pass this field
Since the assembly sequence of the class definition file py from rest_framework Import serializers # serialization component from app01 Import Models class BookSerializer (serializers.Serializer): # serialization details Press, after a specified SerializerMethodField, may correspond to a method, what return content, publish_detail is what publish_detail = serializers.SerializerMethodField (READ_ONLY = True) # corresponding fixed wording get_ field names DEF get_publish_detail (Self, obj): # this obj is app01.models.Book Print (obj, of the type (obj )) return { ' name ' : obj.publish.name, 'city':obj.publish.city} # 返回所有作者信息 authors = serializers.SerializerMethodField(read_only=True) def get_authors(self,obj): return [{'name':author.name,'age':author.age} for author in obj.authors.all()]
Sequence of two ways |
1 Serializers not specify a table model
source: Specifies the sequence of the field, the field may be, it may be a method
SerializerMethodFields usage
Mode. 1: the authors = serializer.SerializerMethodField () DEF get_authors (Self, obj): return { ' name ' : obj.publish.name, ' City ' : obj.publish.city} # expand inferior to query if a complete table write a lot of data that kv value pairs embodiment 2: class AuthorSerializer (serializer.Serializer): name = serializer.CharField () Age = serializer.CharField () the authors = serializer.SerializerMethodField () DEF get_authors (Self, obj): RETAuthorSerializer = (instance = obj.authors.all (), man = True) # instance is the default parameter can not write return ret.data
2 ModelSerializers: specifies the table model
class Meta -: Model = Table Model fields = ( '__all__') to display all fields fields = ( 'id', ' name') displays part of the field exclude = [ 'name'] exclude this field other content are displayed can and fields at the same time use depth = 1 cross-table depth is 1, the official suggested no more than 10, not more than three personal recommendations rewritten in a field outside of Meta, rewrite some fields, the same way as Serializers
class AuthorSerializer (serializers.Serializer): name = serializers.CharField () Age = serializers.CharField () # class Meta: # Fields = ( '__all__') serializers wood have this meta method has only modelserializer class BookSerializer (serializers.ModelSerializer) : class Meta -: model = models.Book # which a model table # fields = ( 'NID', 'name') displayed in field # fields = ( ' __all__ is ' ) # display all the field information # the exclude = [ 'name' ] exclude # # depth =. 1 #Depth is 1, the official suggested no more than 10 individuals recommended not to exceed 3 category = serializers.CharField (Source = ' get_category_display ' ) in the authors = serializers.SerializerMethodField () DEF get_authors (Self, obj): # can write a list of formula If many, then you should write the formula in which a lot of expansion and poor can continue to write the Serializer RET = AuthorSerializer (instance = obj.authors.all (), mANY = True) return ret.data name5 = serializers.CharField (Source = ' name ' ) # rewriting meta name field with the same level or a rewritable manner and Serializers sequence of the same assembly
Deserialization |
1 使用继承了Serializers序列化类的对象,反序列化 在自己写的序列化类中重写create方法,反序列化 重写create放法,实现序列化
在序列化类中: 序列化类中写create方法
from rest_framework import serializers # 序列化组件 class BookSerializer(serializers.Serializer): #反序列化创建 def create(self, validated_data): ret = models.Book.objects.create(**validated_data) return ret
在视图中:
from app01.app01serializer import BookSerializer #自定义py文件里为了和view视图函数隔离开 自定义文件就写serializer组件 class Books(APIView): #使用Serializers序列化类的对象,反序列化 def post(self,request): #实例化产生一个序列化类的对象,data是要反序列化的字典 bookser = BookSerializer(data=request.data) if bookser.is_valid(): #清洗通过的数据 ret = bookser.create(bookser.validated_data) return Response()
2 使用继承了ModelSerializers序列化类的对象,反序列化
在视图中 在视图中写save()
from django.shortcuts import render,HttpResponse,redirect from rest_framework.views import APIView from app01 import models from rest_framework.response import Response #返回用的 # 把对象转成json格式字符串 from app01.app01serializer import BookSerializer #自定义py文件里为了和view视图函数隔离开 自定义文件就写serializer组件 class Books(APIView): # 使用继承了ModelSerializers序列化类的对象,反序列化 def post(self,request): #实例化产生一个序列化类的对象,data是要反序列的字典 bookser = BookSerializer(data=request.data) if bookser.is_valid(raise_exception=True): #抛出的异常前端可以看到 #清洗通过的数据 bookser.save()
反序列化的校验 |
反序列化的校验局部校验 validate_字段名(self,value):
如果校验失败,抛出ValidationError(抛出的异常信息需要去视图层bookser.errors中取)
如果校验通过直接return value
from rest_framework import exceptions 序列化类下面写: #反序列化的校验(局部校验,全局校验) def validate_name(self,value): print(value) raise exceptions.ValidationError('不能以sb开头') # if value.startswith('sb'): # raise ValidationError('不能以sb开头') # return value
视图层 post请求内 校验错误信息 def post(self,request): #实例化产生一个序列化类的对象,data是要反序列化的字典 bookser=BookSerializer(data=request.data) # bookser.data if bookser.is_valid(raise_exception=True): #清洗通过的数据 bookser.save() else: print(bookser.errors['name'][0]) return Response()
反序列化的校验全局 validate(self,attrs) attrs所有校验通过的数据,是个字典 如果校验失败,抛出ValidationError 如果校验通过直接返回return attrs
序列化组件类中 #去局校验 def validate(self,attrs): print(attrs) return attrs
独源码分析 |
全局和局部钩子源码部分
在序列化的时候,传many=True和many=False,生成的对象并不是一个对象
bookse.data 之前执行过,直接返回
get_attribute(instance,self.source_attrs)
self.source_attrs 是source指定的通过,切分后的列表
instance 当前循环到的book对象