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)
四 . 为了避免代码重复接下来有个进化版的视图函数
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',
})),