码迷,mamicode.com
首页 > 其他好文 > 详细

rest-framework序列化

时间:2018-10-05 17:26:55      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:rtc   并且   查看   key   pattern   ref   信息   add   没有   

快速实例

Quickstart

序列化

开篇介绍:

     ----  一切皆是资源,操作只是请求方式
     
     ----book表增删改查
         /books/                 books
         /books/add/             addbook
         /books/(\d+)/change/    changebook
         /books/(\d+)/delete/    delbook
         
    ----book表增删改查
         /books/     -----get            books      -----  返回当前所有数据
         /books/     -----post           books      -----  返回提交数据 
         
         /books/(\d+)-----get            bookdetail -----  返回当前查看的单条数据 
         /books/(\d+)-----put            bookdetail -----  返回更新数据 
         /books/(\d+)-----delete         bookdetail -----  返回空
         
              
         class  Books(View):
              def get(self,request):
                  pass  # 查看所有书籍
                  
              def post(self,request):
                  pass  # 添加书籍
                  
                  
         class  BooksDetail(View):
              def get(self,request,id):
                  pass  # 查看具体书籍
         
              def put(self,request,id):
                  pass  # 更新某本书籍
                  
              def delete(self,request,id):
                  pass  # 删除某本书籍      
         

 

创建一个序列化类

简单使用

开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式。我们可以通过声明与Django forms非常相似的序列化器(serializers)来实现。

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",on_delete=models.CASCADE)
    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

views部分:

 

from django.shortcuts import render,HttpResponse
import json
from django.views import View
from .models import *
from app01.serialize import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import serializers   #这是rest_framework的序列化组件

#为queryset(需要加many=True),model对象做序列化 class PublishSerializers(serializers.Serializer): name =serializers.CharField() email=serializers.CharField() class PublishView(APIView): def get(self,request): #取数据 print(request.GET) publish_list = Publish.objects.all() #序列化 #方式一: #publish_list=list(Publish.objects.all().values("name","email")) #方式二: # 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)) #方式三 # from django.core import serializers # publish_list = Publish.objects.all() # ret=serializers.serialize("json",publish_list) #方式四(restframework序列化) ps=PublishSerializers(publish_list,many=True) return HttpResponse(ps.data)

一对多和多对多字段的序列化:

class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    pub_date = serializers.DateField()

    publish = serializers.CharField(source="publish.email")  # 一对多字段使用source字段处理

    # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        temp = []
        for obj in obj.authors.all():
            temp.append(obj.name)
        return temp

序列化的过程:

‘‘‘
序列化BookSerializers(book_list,many=True)过程:
    temp=[]
    for obj in book_list:
        temp.append({
            "title":obj.title,
            "price":obj.price,
            "pub_date":obj.pub_date,
            #"publish":str(publish),
            "publish":obj.publish.name,
            "authors":get_authors(obj)

        })
‘‘‘

 

ModelSerializer(类似于ModelForm):

class PublishModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = "__all__"

提交post请求:

    def post(self,request):
        #原生request支持的操作
        # print(request.POST)
        # print(request.body)
        # print(type(request))
        from django.core.handlers.wsgi import WSGIRequest


        #新的request支持的操作
        print("request_data",request.data) #request_data {‘name‘: ‘jesi‘, ‘email‘: ‘666@qq.com‘}
        print("request_data_type",type(request.data))   #request_data_type <class ‘dict‘>

        return HttpResponse("POST")

get和post:

class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        # bs=BookSerializers(book_list,many=True)
        bs2=BookModelSerializers(book_list,many=True,context={request: request})
        # return Response(bs.data)
        return Response(bs2.data)


    def post(self,request):
        #post请求的数据
        bs=BookModelSerializers(data=request.data)
     #post请求过来的数据如果通过了校验就创建一条数据,如果没有返回错误信息。
if bs.is_valid(): bs.save() return Response(bs.data) else: return Response(bs.errors)

 

重写save中的create方法:

# ModelSerializers
class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"
    # publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理              

  

    # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
    def create(self, validated_data):
        print(validated_data)
        book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                   pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
        book.authors.add(*validated_data["authors"])
        return book

 整体:

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

    publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理

    #
    # #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
    # authors=serializers.SerializerMethodField()
    # def get_authors(self,obj):
    #     temp=[]
    #     for obj in obj.authors.all():
    #         temp.append(obj.name)
    #     return temp

    # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
    def create(self, validated_data):
        print(validated_data)
        book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                   pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
        book.authors.add(*validated_data["authors"])
        return book

 

 单条数据的get和put请求:

直接通过序列化的实例对象做一个校验,对传入的ID值对应的书籍进行增删改查。

class BookDetailView(APIView):
    def get(self,request,id):
        #单条数据查看
        book=Book.objects.filter(pk=id).first()
        bs=BookModelSerializers(book,context={request: request})
        return Response(bs.data)

    def put(self,request,id):
        #更新单条数据
        book=Book.objects.filter(pk=id).first()

        bs = BookModelSerializers(book,request.data)
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return Response(bs.errors)

    def delete(self,request,id):
        Book.objects.filter(pk=id).delete()
        return Response()

 

超链接API:Hyperlinked

class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"
    publish=serializers.HyperlinkedIdentityField(
        view_name="publishdetail",
        lookup_field="publish_id",
        lookup_url_kwarg="id",

    )

urls部分:

urlpatterns = [
    path(admin/, admin.site.urls),
    url(rpublishes/$, views.PublishView.as_view(),name="publish"),
    url(rpublishes/(?P<id>\d+)/$, views.PublishDetailView.as_view(),name="publishdetail"),
    url(rbooks/$, views.BookView.as_view(),name="books"),
    url(rbooks/(\d+)/$, views.BookDetailView.as_view(),name="bookdetail"),
] 

 这里有一个点需要注意一下:

class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        # bs=BookSerializers(book_list,many=True)
        bs2=BookModelSerializers(book_list,many=True,context={request: request})
        # return Response(bs.data)
        return Response(bs2.data)



class BookDetailView(APIView):
    def get(self,request,id):
        #单条数据查看
        book=Book.objects.filter(pk=id).first()
        bs=BookModelSerializers(book,context={request: request})
        return Response(bs.data)

 最后总结:

总结:
        1 reuqest类----源码
        
        2 restframework 下的APIView--源码
        
          url(r^books/$, views.BookView.as_view(),name="books")#  View下的view

          books/一旦被访问: view(request) ------APIView: dispatch()
        
        3 def dispatch():
        
              构建request对象
              self.request=Request(request)
              self.request._request
              self.request.GET  # get
              self.request.data # POST  PUT
          
              分发----if get请求:
                    if request.method.lower() in self.http_method_names:
                        handler = getattr(self, request.method.lower(),
                                         self.http_method_not_allowed)
                    else:
                        handler = self.http_method_not_allowed   

                    response = handler(request, *args, **kwargs) # self.get(request, *args, **kwargs)
                    
                    return response                
            
        4 序列化类
            # from django.core import serializers
            # ret=serializers.serialize("json",publish_list)
        
            restframework下的序列类  BookModelSerializers
                将queryset或者model对象序列成一json数据
                    bs=BookModelSerializers(book_list,many=True,context={request: request})
                    bs=BookModelSerializers(book,context={request: request})
           
                还可以做校验数据,json-------》queryset/model-->记录
                
                    bs=BookModelSerializers(data=request.data)
                    if bs.is_valid():
                        print(bs.validated_data)
                        bs.save() # 重写create方法
        5 操作数据:
        
            以Book表为例
                class BookView(APIView):
                    # 查看所有书籍
                    def get(self,request):
                        book_list=Book.objects.all()
                        bs=BookModelSerializers(book_list,many=True,context={request: request})
                        return Response(bs.data)
                        
                    # 添加一本书籍    
                    def post(self,request):
                        # post请求的数据
                        bs=BookModelSerializers(data=request.data)
                        if bs.is_valid():
                            print(bs.validated_data)
                            bs.save()# create方法
                            return Response(bs.data)
                        else:
                            return Response(bs.errors)

                class BookDetailView(APIView):
                    # 查看一本书籍
                    def get(self,request,id):

                        book=Book.objects.filter(pk=id).first()
                        bs=BookModelSerializers(book,context={request: request})
                        return Response(bs.data)
                    # 更新一本书籍
                    def put(self,request,id):
                        book=Book.objects.filter(pk=id).first()
                        bs=BookModelSerializers(book,data=request.data)
                        if bs.is_valid():
                            bs.save()
                            return Response(bs.data)
                        else:
                            return Response(bs.errors)
                    # 删除某一本书籍
                    def delete(self,request,id):
                        Book.objects.filter(pk=id).delete()

                        return Response()

代码:

views.py

技术分享图片
from django.shortcuts import render,HttpResponse
import json
from django.views import View
from .models import *
from app01.serialize import *
from rest_framework.views import APIView
from rest_framework.response import Response

class PublishView(APIView):

    def get(self,request):
        #取数据
        print(request.GET)
        publish_list = Publish.objects.all()

        #序列化
        #方式一:
        #publish_list=list(Publish.objects.all().values("name","email"))

        #方式二:
        # 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))

        #方式三
        # from django.core import serializers
        # publish_list = Publish.objects.all()
        # ret=serializers.serialize("json",publish_list)

        #方式四(restframework序列化)
        ps=PublishSerializers(publish_list,many=True)
        return HttpResponse(ps.data)


    def post(self,request):
        #原生request支持的操作
        # print(request.POST)
        # print(request.body)
        # print(type(request))
        from django.core.handlers.wsgi import WSGIRequest


        #新的request支持的操作
        print("request_data",request.data) #request_data {‘name‘: ‘jesi‘, ‘email‘: ‘666@qq.com‘}
        print("request_data_type",type(request.data))   #request_data_type <class ‘dict‘>

        return HttpResponse("POST")


class PublishDetailView(APIView):
    def get(self,request,id):
        #单条数据查看
        publish=Publish.objects.filter(pk=id).first()
        ps=PublishModelSerializers(publish)
        return Response(ps.data)

    def put(self,request,id):
        #更新单条数据
        publish=Publish.objects.filter(pk=id).first()

        ps = PublishModelSerializers(publish,request.data)
        if ps.is_valid():
            ps.save()
            return Response(ps.data)
        else:
            return Response(ps.errors)

    def delete(self,request,id):
        Publish.objects.filter(pk=id).delete()
        return Response()



class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        # bs=BookSerializers(book_list,many=True)
        bs2=BookModelSerializers(book_list,many=True,context={request: request})
        # return Response(bs.data)
        return Response(bs2.data)


    def post(self,request):
        #post请求的数据
        bs=BookModelSerializers(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,id):
        #单条数据查看
        book=Book.objects.filter(pk=id).first()
        bs=BookModelSerializers(book,context={request: request})
        return Response(bs.data)

    def put(self,request,id):
        #更新单条数据
        book=Book.objects.filter(pk=id).first()

        bs = BookModelSerializers(book,request.data)
        if bs.is_valid():
            bs.save()
            return Response(bs.data)
        else:
            return Response(bs.errors)



    def delete(self,request,id):
        Book.objects.filter(pk=id).delete()
        return Response()
View Code

serialize.py

技术分享图片
# Author:Jesi
# Time : 2018/10/5 11:29
from app01.models import *
from rest_framework import serializers   #这是rest_framework的序列化组件
#为queryset(需要加many=True),model对象做序列化
class PublishSerializers(serializers.Serializer):
    name =serializers.CharField()
    email=serializers.CharField()


# Serializers
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    pub_date = serializers.DateField()

    publish = serializers.CharField(source="publish.email")  # 一对多字段使用source字段处理

    # 多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
    authors = serializers.SerializerMethodField()

    def get_authors(self, obj):
        temp = []
        for obj in obj.authors.all():
            temp.append(obj.name)
        return temp


‘‘‘
序列化BookSerializers(book_list,many=True)过程:
    temp=[]
    for obj in book_list:
        temp.append({
            "title":obj.title,
            "price":obj.price,
            "pub_date":obj.pub_date,
                                                        #"publish":str(publish),
            "publish":obj.publish.name,
            "authors":get_authors(obj)

        })
‘‘‘

class PublishModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = "__all__"

# ModelSerializers
class BookModelSerializers(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = "__all__"
    publish=serializers.HyperlinkedIdentityField(
        view_name="publishdetail",
        lookup_field="publish_id",
        lookup_url_kwarg="id",

    )

    # publish = serializers.CharField(source="publish.pk")  # 一对多字段使用source字段处理

    #
    # #多对多使用下面字段,并且配一个方法,方法里面可自定义任意东西,可取作者表的名字。
    # authors=serializers.SerializerMethodField()
    # def get_authors(self,obj):
    #     temp=[]
    #     for obj in obj.authors.all():
    #         temp.append(obj.name)
    #     return temp

    # 因为上面自定制了字段,所以这个添加方法需要重写才可以。
    def create(self, validated_data):
        print(validated_data)
        book = Book.objects.create(title=validated_data["title"], price=validated_data["price"],
                                   pub_date=validated_data["pub_date"], publish_id=validated_data["publish"]["pk"])
        book.authors.add(*validated_data["authors"])
        return book
View Code

urls.py

技术分享图片
from django.contrib import admin
from django.urls import path
from django.conf.urls import url
from app01 import views
urlpatterns = [
    path(admin/, admin.site.urls),
    url(rpublishes/$, views.PublishView.as_view(),name="publish"),
    url(rpublishes/(?P<id>\d+)/$, views.PublishDetailView.as_view(),name="publishdetail"),
    url(rbooks/$, views.BookView.as_view(),name="books"),
    url(rbooks/(\d+)/$, views.BookDetailView.as_view(),name="bookdetail"),
]
View Code

 

 

rest-framework序列化

标签:rtc   并且   查看   key   pattern   ref   信息   add   没有   

原文地址:https://www.cnblogs.com/geogre123/p/9744937.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!