DRF的序列化器serializers
DRF的序列化器的主要作用是将不同请求的数据“序列化”为指定格式的数据结构返回给接口的调用者。
视图函数中使用DRF中的Response返回数据 —— 返回的数据按照规范一定是一个能被序列化的“字典” —— 如果失败,返回的字典中要有状态码及错误的信息。
序列化器serializers的使用可以参照forms的Form组件与ModelForm组件的使用,它们的使用方式十分的相似。
自定义的序列化器的类可以继承Serializer,也可以继承ModelSerializer。
使用Serializer进行序列化的方法可以参见这个例子:基于DRF的图书增删改查练习
下面介绍一下ModelSerializer的使用!
ModelSerializer的使用
有Model如下
from django.db import models class Publisher(models.Model): name = models.CharField(max_length=32) class Author(models.Model): name = models.CharField(max_length=32) class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(decimal_places=2,max_digits=5) pub_date = models.DateField(auto_now=True) category = models.IntegerField(choices=((1,'娱乐'),(2,'科技'),(3,'财经')),default=1) pub = models.ForeignKey(to=Publisher,on_delete=models.CASCADE) authors = models.ManyToManyField(Author)
路由如下
主路由做了分发:
from django.contrib import admin from django.urls import path,re_path,include urlpatterns = [ path('admin/', admin.site.urls), re_path('^book/', include(('book.urls','book'))), ]
分路由如下:
from django.urls import path,re_path from book import views urlpatterns = [ re_path(r'^books/$',views.BookView.as_view(),name='books'), re_path(r'^book/(\d+)/$',views.BookDetail.as_view(),name='book_detail'), ]
视图函数如下:—— 注意视图中是用Response返回的~
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from book import models from book.my_serializers import BookSerializers class BookView(APIView): def get(self,request): queryset = models.Book.objects.all() # 多个对象,需要加many=True ser_obj = BookSerializers(queryset,many=True) return Response(ser_obj.data) def post(self,request): ser_obj = BookSerializers(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) class BookDetail(APIView): # 获取一个对象 def get(self,request,pk): queryset = models.Book.objects.filter(pk=pk).first() ser_obj = BookSerializers(queryset) return Response(ser_obj.data) def put(self,request,pk): book_obj = models.Book.objects.filter(pk=pk).first() # 需要加参数~partial=True表示可以局部更新 ser_obj = BookSerializers(instance=book_obj,data=request.data,partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) def delete(self,request,pk): book_obj = models.Book.objects.filter(pk=pk).first() if book_obj: book_obj.delete() return Response({'status':200,'msg':'删除成功'}) else: return Response({'status':404,'msg':'删除的书籍不存在!'})
自定义的序列化器如下(使用ModelSerializer):
# -*- coding:utf-8 -*- from rest_framework import serializers from book import models # 出版社的序列化器 class PubSerializers(serializers.ModelSerializer): class Meta: model = models.Publisher # 只显示name fields = ['name'] # 作者的序列化器 class AuthorSerializers(serializers.ModelSerializer): class Meta: model = models.Author # 显示所有字段 fields = '__all__' # 书籍的序列化器 # 利用ModelSerializer class BookSerializers(serializers.ModelSerializer): category_info = serializers.SerializerMethodField() pub_info = serializers.SerializerMethodField() authors_info = serializers.SerializerMethodField() # choices字段的数据 def get_category_info(self,book_obj): return book_obj.get_category_display() # 外键字段的数据 —— 用另外一个序列化器 def get_pub_info(self,book_obj): pub_obj = book_obj.pub ser_obj = PubSerializers(pub_obj) return ser_obj.data # 多对多关系的数据 —— 用另外一个序列化器 def get_authors_info(self,book_obj): # 记得加all()方法 authors_obj = book_obj.authors.all() ser_obj = AuthorSerializers(authors_obj,many=True) return ser_obj.data class Meta: model = models.Book fields = '__all__' # exclute = [] # 注意在序列化器中两个不能一起用! # 额外的配置 —— 以下字段只在写入数据的时候使用 extra_kwargs = { 'category':{'write_only':True}, 'pub':{'write_only':True}, 'authors':{'write_only':True}, }