DjangoRestFramework之序列化组件

一 . serializers

from rest_framework.views import APIView
from app01 import models
from rest_framework.response import Response
from rest_framework import serializers

# 使用serializers 需要先定义一个类,类里面的内容要和models一致
class BookSerializers(serializers.Serializer):
    title = serializers.CharField(max_length=16)
    price = serializers.IntegerField()

class BookHandle(APIView):

    def get(self, request):
        book_msg = models.Books.objects.all()
        res = BookSerializers(book_msg, many=True)  # 当res里面有多个对象(query_set)的时候要指定many=true(必填)
        print(res.data)
        return Response(res.data)  # 可以用rest_framework里面的Response

    def post(self, request):
        # print('post方法==>', request.data)
        res = BookSerializers(data=request.data, many=False)
        if res.is_valid():  # 这个是对传过来数据与models里面的字段是否对应进行验证
            models.Books.objects.create(**res.data)
            return Response(res.data)  # 按照API接口规范,数据存储成功后要返回
        return Response(res.errors)

二 . 学了单表的,来一波跨表的序列化 

from django.db import models

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()

class AuthorDetail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)  # 多对一到Publish表
    authors = models.ManyToManyField(to='Author', )  # 多对多到Author表

  多对一的外键序列化展示,在没有写source之前

 

  写了source之后

  

  多对多的外键序列化展示

  

  

  

 三 . 用ModelSerializer序列化

     基于ModelSerializer的get,post,put,delete的用法

 1 from rest_framework.response import Response
 2 from rest_framework.views import APIView
 3 from rest_framework import serializers
 4 from app01 import models
 5 
 6 class BookSerializer(serializers.ModelSerializer):
 7     class Meta:
 8         model = models.Book
 9         fields = '__all__'
10 
11     # 关于外键序列化要写在这个类里面
12     # 下面这两个变量千万不要和数据库的名字相同,否则会由于read_only=True被剔除,导致报错
13     publish_list = serializers.CharField(source='publish.name')  # book表中publish外键,多对一
14     authors_list = serializers.SerializerMethodField()  # 多对多的写法
15 
16     def get_authors_list(self, obj):  # 函数名格式必须是get_这个类中对应的属性名,obj就是下面book_obj_list里的每一个对象
17         lst = []
18         authors_list = obj.authors.all()
19         for author in authors_list:
20             dic = {}
21             dic['name'] = author.name
22             lst.append(dic)
23         return lst
24 
25 class BookHandle(APIView):
26     # 获取所有数据
27     def get(self, request):
28         book_obj_list = models.Book.objects.all()
29         book_res = BookSerializer(book_obj_list, many=True)
30         return Response(book_res.data)
31 
32     def post(self, request):
33         # print('post发来的数据=>', request.data)
34         res = BookSerializer(data=request.data, many=False)
35         if res.is_valid():
36             res.save()
37             return Response(res.data)
38         else:
39             return Response(res.errors)
40 
41 # 带参数的单独写一个类,也会有一个单独的视图函数
42 class HaveCanShu(APIView):
43     # 更新数据
44     def put(self, request, id):
45         old_obj = models.Book.objects.filter(pk=id).first()
46         res = BookSerializer(data=request.data, many=False, instance=old_obj)
47         if res.is_valid():
48             res.save()
49             return Response(res.data)
50         else:
51             return Response(res.errors)
52 
53     def delete(self, request, id):
54         models.Book.objects.filter(pk=id).delete()
55         return Response('')  # 执行删除操作后,要返回空字符串
56 
57     def get(self, request, id):
58         book_obj = models.Book.objects.get(pk=id)
59         book_res = BookSerializer(book_obj, many=False)
60         return Response(book_res.data)
get, post, put, delete

四 . 为了避免代码重复接下来有个进化版的视图函数

  all_serializers.py文件

首先我们先把所有的序列化类单独放一个py文件中,我这里放到了all_serializers.py文件中.
from rest_framework import serializers
from app01 import models

class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Publish
        fields = '__all__'

  视图函数

from rest_framework.mixins import CreateModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin, 
    RetrieveModelMixin
from rest_framework import generics

# ListModelMixin 获取所有数据操作
# RetrieveModelMixin 获取一条数据操作
# DestroyModelMixin 删除一体数据操作
# UpdateModelMixin 更新一条数据操作
# CreateModelMixin 添加一条数据操作

class PublishHandle(ListModelMixin, CreateModelMixin, generics.GenericAPIView):
    queryset = models.Publish.objects.all()  # 变量名必须是这个
    serializer_class = PublishSerializer  # 变量名必须是这个

    def get(self, request):
        return self.list(request)

    def post(self, request):
        return self.create(request)

# 有参数的写一个类
class CPublishHandle(UpdateModelMixin, DestroyModelMixin, RetrieveModelMixin, generics.GenericAPIView):
    queryset = models.Publish.objects.all()  # 变量名必须是这个
    serializer_class = PublishSerializer  # 变量名必须是这个

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

  URL

from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^publishes/$', views.PublishHandle.as_view()),
    url(r'^publishes/(?P<pk>d+)/', views.CPublishHandle.as_view()),  # 参数一定要这么写
]

五 . 上边还是有冗余,来一款再进化版

  all_serializers.py文件

from rest_framework import serializers
from app01 import models

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = '__all__'

  视图函数 

from app01 import models
from app01.all_serializers import AuthorSerializer
from rest_framework import generics

class AuthorHandle(generics.ListCreateAPIView):
    queryset = models.Author.objects.all()  # 变量名必须是这个
    serializer_class = AuthorSerializer  # 变量名必须是这个

class CAuthorHandle(generics.RetrieveUpdateDestroyAPIView):
    queryset = models.Author.objects.all()  # 变量名必须是这个
    serializer_class = AuthorSerializer  # 变量名必须是这个

  URL

url(r'^authors/$', views.AuthorHandle.as_view()),
url(r'^authors/(?P<pk>d+)/', views.CAuthorHandle.as_view()),

六 . 终极进化版

  上面还是有一点重复,下面来一个终级进化版

    all_serializers.py文件

class AuthorSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = '__all__'

    视图函数

from rest_framework.viewsets import ModelViewSet
from app01 import models

# 只写一个类就可以啦
class CAuthorHandle(ModelViewSet):
    queryset = models.Author.objects.all()  # 变量名必须是这个
    serializer_class = AuthorSerializer  # 变量名必须是这个

    URL

url(r'^authors/$', views.CAuthorHandle.as_view({
     'get': 'list',
     'post': 'create'
})),
url(r'^authors/(?P<pk>d+)/', views.CAuthorHandle.as_view({
     'get': 'retrieve',
     'put': 'update',
     'delete': 'destroy',
})),

  

原文地址:https://www.cnblogs.com/attila/p/10802342.html