rest-framework之序列化组件

一 Django自带序列化组件

二 rest-framework序列化组件之Serializer

三 rest-framework序列化之ModelSerilizer

四 生成hy.permedialink(极少数)

五 序列化组件之请求数据校验和保存功能

一 Django自带序列化组件

class PublishView(View):
    def get(self,request):
        # 方式一
        publish_list = list(Publish.objects.all().values('name','email'))
        return HttpResponse(json.dumps(publish_list))
        # 方式二
        from django.forms.models import model_to_dict
        publish_list = Publish.objects.all()
        temp = []
        for obj in publish_list:
            temp.append(model_to_dict(obj))
        return HttpResponse(json.dumps(temp))
        # 方式三
        from django.core import serializers
        publish_list = Publish.objects.all()
        temp = serializers.serialize("json",publish_list)
        return HttpResponse(temp)

 二 rest-framework序列化之Serializer

models部分:

from django.db import models

# Create your models here.


class Book(models.Model):
    title=models.CharField(max_length=32)
    price=models.IntegerField()
    pub_date=models.DateField()
    publish=models.ForeignKey("Publish")
    authors=models.ManyToManyField("Author")
    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    def __str__(self):
        return self.name

view部分:

from rest_framework.views import APIView
from rest_framework.response import Response
from .models import *
from django.shortcuts import HttpResponse
from django.core import serializers


from rest_framework import serializers

class BookSerializers(serializers.Serializer):
    title=serializers.CharField(max_length=32)
    price=serializers.IntegerField()
    pub_date=serializers.DateField()
    publish=serializers.CharField(source="publish.name")
    #authors=serializers.CharField(source="authors.all")
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        temp=[]
        for author in obj.authors.all():
            temp.append(author.name)
        return temp
  #此处可以继续用author的Serializers,
  # def get_authors(self,obj):
    #     ret=obj.authors.all()
    #     ss=AuthorSerializer(ret,many=True)
    #     return ss.data

class BookViewSet(APIView):

    def get(self,request,*args,**kwargs):
        book_list=Book.objects.all()
        # 序列化方式1:
        # from django.forms.models import model_to_dict
        # import json
        # data=[]
        # for obj in book_list:
        #     data.append(model_to_dict(obj))
        # print(data)
        # return HttpResponse("ok")

        # 序列化方式2:
        # data=serializers.serialize("json",book_list)
        # return HttpResponse(data)

        # 序列化方式3:
        bs=BookSerializers(book_list,many=True)     #many=True代表有多条数据,如果只有一条数据,many=False
        return Response(bs.data)
     # 序列化方式4: 
      # ret=models.Book.objects.all().values('nid','title')
     # dd=list(ret)
        # return HttpResponse(json.dumps(dd))

注意:

source 如果是字段,会显示字段,如果是方法,会执行方法,不用加括号(authors=serializers.CharField(source='authors.all'))

如在模型中定义一个方法,直接可以在在source指定执行

三 rest-framework序列化之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

四 生成hypermedialink(极少数)

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = "__all__"
    # 生成连接,直接查看出版社详情
    publish = serializers.HyperlinkedIdentityField(view_name='ttt', lookup_field='publish_id', lookup_url_kwarg='pkk')
    authors=serializers.SerializerMethodField()
    def get_authors(self,obj):
        ret=obj.authors.all()
        ss=AuthorSerializer(ret,many=True)
        return ss.data
#--------------

res=BookSerializers(ret,many=True,context={'request': request})
#--------------

class Publish(APIView):
    def get(self,request,pkk):
        print(pkk)
        return HttpResponse('ok')
#----路由---
url(r'^publish/(?P<pkk>\d+)$', views.Publish.as_view(),name='ttt'),

五 序列化组件之请求数据校验和保存功能

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model=Book
        fields="__all__"

#————————
class BookView(APIView):

    def post(self, request):

        # 添加一条数据
        print(request.data)

        bs=BookSerializers(data=request.data)
        if bs.is_valid():
            bs.save()  # 生成记录
            return Response(bs.data)
        else:

            return Response(bs.errors)

通过源码查看校验字段的钩子函数:

#is_valid---->self.run_validation-(执行Serializer的run_validation)-->self.to_internal_value(data)---(执行Serializer的run_validation:485行)
def validate_title(self, value):
        from rest_framework import exceptions
        raise exceptions.ValidationError('看你不顺眼')
        return value

#全局
def validate(self, attrs):
    from rest_framework import exceptions
    if attrs.get('title')== attrs.get('title2'):
        return attrs
    else:
        raise exceptions.ValidationError('不想等啊')

图书的增删查改restful接口:

视图层:

class BookSerializers(serializers.ModelSerializer):
    class Meta:
        model=models.Book
        fields='__all__'


class BookView(APIView):

    def get(self, request):
        book_list = models.Book.objects.all()
        bs = BookSerializers(book_list, many=True)
        # 序列化数据

        return Response(bs.data)

    def post(self, request):
        # 添加一条数据
        print(request.data)

        bs=BookSerializers(data=request.data)
        if bs.is_valid():
            bs.save()  # 生成记录
            return Response(bs.data)
        else:

            return Response(bs.errors)

class BookDetailView(APIView):
    def get(self,request,pk):
        book_obj=models.Book.objects.filter(pk=pk).first()
        bs=BookSerializers(book_obj,many=False)
        return Response(bs.data)
    def put(self,request,pk):
        book_obj = models.Book.objects.filter(pk=pk).first()

        bs=BookSerializers(data=request.data,instance=book_obj)
        if bs.is_valid():
            bs.save() # update
            return Response(bs.data)
        else:
            return Response(bs.errors)
    def delete(self,request,pk):
        models.Book.objects.filter(pk=pk).delete()

        return Response("")
View Code

路由:

url(r'^books/$', views.BookView.as_view()),
url(r'^books/(?P<pk>\d+)$', views.BookDetailView.as_view()),
View Code

 

posted @ 2018-10-22 16:14  每天都要开心的过  阅读(314)  评论(0编辑  收藏  举报