django和restframework的序列化

django自带的序列化组件(了解,不好控制)

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


# 会把所有的字段都取出来,很多无用信息,不好控制

 

rest_framework的serializers组件

# 新建一个py文件,写上需要序列化的字段
from rest_framework import serializers
from apps import models


class bookser(serializers.Serializer):
    name = serializers.CharField()
    publish = serializers.CharField()

# 在view里序列化表
from rest_framework.response import Response
from apps import models
from rest_framework.views import APIView
from apps.app01_serializer.app01_ser import Bookser
class test(APIView):
   def get(self,request,*args,**kwargs):
      book_obj = models.book.objects.all()
      books = Bookser(book_obj,many=True)
      return Response(books.data)



得到页面:注意要在settings的app里注册rest_framework
只序列化得到了需要的字段


source
序列化字段的名字和表中的一一对应,如果不对应则无法序列化,我们可以加source参数
class bookser(serializers.Serializer):
  name = serializers.CharField()
  name5 = serializers.CharField(source='name')
  注意:source不能和定义的字段名一样,不然会报错
  publish = serializers.CharField()

# 如果book表外键关联publish,我们想要获取publish的city
class bookser(serializers.Serializer):
  name5 = serializers.CharField(source='name')
  publish = serializers.CharField(soucre='publish.city')

# source不但可以指定一个字段,还可以指定一个方法
 models.py
from django.db import models
class book(models.Model):
    name = models.CharField(max_length=16)
    
  def test(self):
    return 'xxx'

book_ser.py文件
class bookser(serializers.Serializer):
  name = serializers.CharField()
  xxx = serializers.CharField(source = 'test')

拿字段的中文
'get_字段名_display' models.py xx = models.IntegerField(choices=((0,'文学类'),(1,'情感类')),default=1)
book_ser.py文件
  # xx = serializers.CharField(source = 'get_字段名_display')   
  xx = serializers.CharField(source = 'get_xx_display')

 

ModelSerializer

book_ser.py
from rest_framework import serializers
from apps import models

class Bookser(serializers.Serializer):
    name = serializers.CharField()
    publish = serializers.CharField(source='publish.name')
    # 指定ModelSerializer之后,可以对应一个方法,返回什么内容,publish_detail就是什么内容
    publish_detail = serializers.SerializerMethodField()
    # 对应的方法是固定写法(get_字段名)
    def get_publish_detail(self,obj):
        return {'name':obj.publish.name,'city':obj.publish.city}

class AuthorsSerialiser(serializers.Serializer):   
  name
= serializers.CharField()   
  age
= serializers.CharField()


class Bookser(serializers.Serializer):   name = serializers.CharField()   publish = serializers.CharField(source='publish.name')   authors = serializers.SerializerMethodField()   def get_authors(self,obj):     authors_ser = AuthorsSerialiser(obj.authors.all(),many=True)       return authors_ser.data

write_only和read_only

# write_only  序列化的时候不显示
# read_only   反序列化的时候不传

序列化book表时,字段price可以不显示,只需定义
price = serializers.CharField(write_only=Ture)

反序列化

# 序列化类中 apps_ser.py
class book_ser(serializers.Serializer):
    ...
    ...
    def create(self,validated_data):
        ret = model.Book.objects.create(**validated_data)
        return ret

# 在视图view.py
    def post(self,request):
        bookser = BookSerializer(data=request.data)
        if bookser.isvalid():
            ret = bookser.create(bookser.validated_data)
        return Response()

 

反序列化中的ModelSerializer

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        # fields = "__all__"
        fields=['nid','title','authors','publish']
        # exclude=('nid',)   #不能跟fields同时用
        # depth = 1    #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层
    publish=serializers.SerializerMethodField()
    def get_publish(self,obj):
        return obj.publish.name
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=obj.authors.all()
        ss=AuthorSerializer(ret,many=True)
        return ss.data


view.py
def post(self,request):   # 实例化产生一个序列化对象,data是要反序列化的字典   bookser = BookSerializer(data=request.data)   if bookser.is_valid():     # 数据通过清洗     bookser.save()   return Response()

反序列化中的效验(局部效验和全局效验)

# 局部效验name字段
def validate_name(self,value):
  if value.startswith('sb'):
    raise ValidationError('不能以sb'开头)
  return value



# 全局效验
def validate(self,attrs):
  if attrs.get('name')==attrs.get('price'):
    raise ValidationErroe('name和price相等,不正常')
  return attrs



view.py
def post(self,request):
  # 实例化产生一个序列化对象,data是要反序列化的字典
  bookser = BookSerializer(data=request.data)
  if bookser.is_valid(raise_exception=True):
    # 通过清洗数据
    # 数据通过清洗
    bookser.save()
  else:
    print(bookser.error['name'][0])

  return Response()

 

 

 

 

 

 

 

 

 

posted @ 2020-08-10 12:05  不忘初心❤  阅读(153)  评论(0编辑  收藏  举报