rest framework-序列化-长期维护

###############   表结构    ###############

from django.db import models


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

 

###############   序列化类  ###############

from rest_framework import serializers
from app01.models import *
# 为queryset,model对象做序列化


class PublishSerializers(serializers.Serializer):
    name = serializers.CharField()
    email = serializers.CharField()


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


class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=32)
    price = serializers.IntegerField()
    pub_date = serializers.DateField()
    publish=serializers.CharField(source="publish.name")  # 这是一对多的字段,需要特殊处理,就使用source就可以了
    #authors=serializers.CharField(source="authors.all")  # 这是多对多的字段,需要特殊处理,但是展示的样式不好,
    authors = serializers.SerializerMethodField()  # 这是多对多字段更好的实现方法,一定要实现一个对应的方法,格式就是get_字段的名字,
    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(obj.publish), # obj.publish.name
            #"authors":obj.authors.all,
            "authors": get_authors(obj)
         })

'''


class BookModelSerializers(serializers.ModelSerializer):  # 这个Serializer就类似form,这个ModelSerializer就类似于modelform,
    class Meta:
        model = Book
        fields = "__all__"  # 这里面实现了一对多和多对多,一对多是展示的id,多对多是展示的一个id列表,

    #publish=serializers.CharField(source="publish.pk")  # 如果你不写单个的字段就是用ModelSerializer的,如果你自己写了就用你自己的,
    # publish=serializers.HyperlinkedIdentityField(  # 超链接
    #         view_name="detailpublish",  #detailpublish 这是publisher的链接,detailpublish这是路由的地方写的别名,链接地址,
    #         lookup_field="publish_id",
    #         lookup_url_kwarg="pk"
    # )


    # authors=serializers.CharField(source="authors.all")
    # 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):  # 如果你自定义了一对多的字段,是不支持source写法的,你需要重写create方法,
    #     print("validated_data",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 AuthorModelSerializers(serializers.ModelSerializer):
    class Meta:
        model=Author
        fields="__all__"

 

###############   视图   ###############

from django.shortcuts import render,HttpResponse
from django.views import View
from rest_framework.response import Response
from app01.models import *
from app01.serilizer import *
from rest_framework.views import APIView
from app01.utils import *
from rest_framework import mixins
from rest_framework import generics
from rest_framework import viewsets
from app01.models import User,Book
from rest_framework.parsers import JSONParser
from rest_framework.response import Response

class PublishView(APIView):  #这个apiview就是rest_framework 的
    def get(self,request):

        # restframework
        # 取数据
        # print("request.data", request.data)
        # print("request.data type", type(request.data))
        # print(request._request.GET)
        # print(request.GET)
        # 序列化
        # 方式1:
        # publish_list=list(Publish.objects.all().values("name","email"))

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

        # 方式3:
        # from django.core import serializers
        # ret=serializers.serialize("json",publish_list)

        # 序列组件
        publish_list = Publish.objects.all()  # 这是一个queryset对象,
        ps = PublishModelSerializers(publish_list, many=True)  # PublishModelSerializers这个类就是为了序列化创建的,many=True这个参数一定要有,
        return Response(ps.data)

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


        # post请求的数据
        ps = PublishModelSerializers(data=request.data)
        if ps.is_valid():
            print(ps.validated_data)
            ps.save()  # 里面有create方法
            return Response(ps.data)
        else:
            return Response(ps.errors)


class PublishDetailView(APIView):
    def get(self, request, pk):

        publish = Publish.objects.filter(pk=pk).first()
        ps = PublishModelSerializers(publish)
        return Response(ps.data)

    def put(self, request, pk):
        publish = Publish.objects.filter(pk=pk).first()
        ps = PublishModelSerializers(publish, data=request.data)
        if ps.is_valid():
            ps.save()
            return Response(ps.data)
        else:
            return Response(ps.errors)

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

        return Response()

class BookView(APIView):
    # authentication_classes = [TokenAuth]
    # permission_classes = []
    # throttle_classes = []
    # parser_classes = [JSONParser]
    def get(self,request):
        book_list=Book.objects.all()
        print(book_list)

        # 分页:

        pnp=MyPageNumberPagination()
        books_page=pnp.paginate_queryset(book_list,request,self)
        #这样就分页完成了,
        bs=BookModelSerializers(books_page,many=True,context={'request': request})

        # bs = BookModelSerializers(book_list, many=True, context={'request': request})

        print(bs.data)
        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})  # 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()

 

###############  路由    ###############

from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^publishes/$', views.PublishView.as_view(),name="publish"), #  View:view(request)=====APIView:dispatch()
    url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"), #  View:view(request)=====APIView:dispatch()
    # url(r'^books/$', views.BookView.as_view(),name="books"),
    # url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"),
    
]

 

###############   序列化总结    ###############

 

这么一总结,也没有多少东西,

#######
1,使用serializers.Serializer
2,使用serializers.ModelSerializer

######
1,单个字段
2,一对多字段
3,多对多字段
4,超链接字段

#######
1,操作所有数据的查看
2,操作单个数据的新增
3,操作单个数据的查看
4,操作单个数据的修改
5,操作单个数据的删除

 

###############   序列化    ###############

 

posted @ 2020-02-11 07:01  技术改变命运Andy  阅读(175)  评论(0编辑  收藏  举报