Fork me on github

Djangorestframework之序列化组件

Django自带序列化组件

这是原生的django序列化组件 但是因为只能对所有的内容进行序列化 ,拓展性太差,所以我们基本启弃用

from django.core import serializers
def test(request):
    book_list = Book.objects.all()    
    ret = serializers.serialize("json", book_list)
    return HttpResponse(ret)

drf序列化的两种方式

第一种:  Serializers

  1 新建一个序列化类继承Serializer
  2 在类中写要序列化的字段

在视图中使用序列化的类
  1 实例化序列化的类产生对象,在产生对象的时候,传入需要序列化的对象(queryset)
  2 对象.data
  3 return Response(对象.data)
高级用法:
  source:可以指定字段(name publish.name),可以指定方法,
  SerializerMethodField搭配方法使用(get_字段名字)
  publish_detail=serializers.SerializerMethodField(read_only=True)
  def get_publish_detail(self,obj):
  return {'name':obj.publish.name,'city':obj.publish.city}
  read_only:反序列化时,不传
  write_only:序列化时,不显示

from rest_framework import serializers
class AuthorSerializer(serializers.Serializer):
    name=serializers.CharField()
    age=serializers.CharField()
class BookSerializer(serializers.Serializer):
#     #指定source='name' ,表示序列化模型表中的name字段,重名命为name5(name和source='name'指定的name不能重名)
    name5=serializers.CharField(source='name')
#     #write_only 序列化的时候,该字段不显示
#     #read_only 反序列化的时候,该字段不传
    price=serializers.CharField(write_only=True)
#     #如果要取 出版社的city source='publish.city'
    publish=serializers.CharField(source='publish.name')
#     #source不但可以指定一个字段,还可以指定一个方法
#     book_type = serializers.CharField(source='get_xx_display',read_only=True)
#     #序列化出版社的详情,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容
    publish_detail=serializers.SerializerMethodField(read_only=True)
#     #对应的方法固定写法get_字段名
    def get_publish_detail(self,obj):
        # print(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()]
        authorser=AuthorSerializer(obj.authors.all(),many=True)
        return authorser.data

    def create(self, validated_data):
        ret=models.Book.objects.create(**validated_data)
        return ret

第二种: ModelSerialzers

继承该类就指定了表模型
  class Meta:
  model=表模型
  1要显示的字段
  fields='__all__'
  fields=('id','name')(注释:列表元组均可以)
  2要排除的字段
  exclude=('name')
  3深度控制
  depth=1
  4重写某个字段
  在Meta外部,重写某些字段,方式同Serializers

 

from rest_framework import serializers
class AuthorSerializer(serializers.Serializer):
    name=serializers.CharField()
    age=serializers.CharField()
    
    
from rest_framework import serializers
from rest_framework import exceptions
from rest_framework.exceptions import ValidationError
from app01 import models

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Book
        # fields=('nid','name')
        #不能跟fields同时使用
        # exclude=['name',]
        fields=('__all__')
        #深度是1,官方建议不要超过10,个人建议不要超过3
        # depth=1
    xx=serializers.CharField(source='get_xx_display')
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=AuthorSerializer(instance=obj.authors.all(),many=True)
        return ret.data
    name=serializers.CharField()
    #反序列化的校验(局部校验,全局校验)
    def validate_name(self,value):

 

反序列化

-使用继承了Serializers序列化类的对象,反序列化
-在自己写的序列化类中重写create方法
-重写create方法,实现序列化
-在序列化类中:

def create(self, validated_data):
ret=models.Book.objects.create(**validated_data)
return ret

 

-在视图中:

def post(self,request):
bookser=BookSerializer(data=request.data)
if bookser.is_valid():
ret=bookser.create(bookser.validated_data)
return Response()

反序列化的校验

validate_字段名(self,value):
  如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
  如果校验通过直接return value
validate(self,attrs)
  attrs所有校验通过的数据,是个字典
  如果校验失败,抛出ValidationError
  如果校验通过直接return attrs

   def validate_name(self,value):

        print(value)
        # raise exceptions.ValidationError('不能以sb开头')
        if value.startswith('sb'):
            raise ValidationError('不能以sb开头')
        return value

    def validate(self,attrs):
        print(attrs)
        # if attrs.get('price')!=attrs.get('xx'):
        #     raise exceptions.ValidationError('name和price相等,不正常')
        return attrs

 

posted @ 2019-07-02 21:54  khan369  阅读(385)  评论(0编辑  收藏  举报