使用ModelSerializer序列化器如何写接口?这里源码demo都写全了~一看就懂! 
上篇ModelSerializer序列化器做了一个小demo,演示了如何操作单表进行序列化和反序列化来实现五个API的使用,多表大差不差??,这里对四个表写五个API接口
单表操作序列化类demo:
# ModelSerializer和表模型有绑定关系class BookSerializer1(serializers.ModelSerializer): class Meta: model = Book # 指定和哪个表有关系 # 所有字段 # fields = '__all__' # 这里注意id字段是从表模型映射过来的,auto自增的,不传也可以 # 自定制的字段不传必须注册,在列表中 fields = ['id', 'title', 'price', 'price_info'] # 指定字段 extra_kwargs = { 'title': {'write_only': True, 'max_length': 8, 'min_length': 3} } # 指定序列化的字段:两种写法:在序列化类中写;models中写 price_info = serializers.SerializerMethodField() def get_price_info(self, obj): return "价格是:" + str(obj.price) ''' 注意:自定制字段如果和表模型获取到的字段是同名,那么自定制返回给前端的字段值就被自定制覆盖了,比如: title = serializers.SerializerMethodField() def get_title(self, obj): return "书名是:" + str(obj.title) ''' # 局部和全局钩子,跟之前一样,但是要注意写在Meta外from rest_framework.views import APIViewfrom .models import Bookfrom rest_framework.response import Responsefrom app01.serializer import BookSerializer1class BookView1(APIView): def get(self, request): # 从数据库查数据,做序列化 book_list = Book.objects.all() # 实例化类,传入初始化的参数,instance和many ''' instance:要序列化的对象 qs,单个对象 many:如果是qs对象,many=True,如果是单个对象many=False ''' ser = BookSerializer1(instance=book_list, many=True) # ser.data使用模型类的对象得到序列化后的字典 return Response(ser.data) def post(self,request): # 反序列化,保存到数据库使用data参数 deser = BookSerializer1(data=request.data) # 校验数据 if deser.is_valid(): # 保存需要重写create方法,不然不知道存到哪个表 deser.save() return Response(deser.data) return Response({'code':101,'msg':'校验不通过','errors':deser.errors})# 处理修改再写一个视图类,防止get冲突class BookDetailView1(APIView): def get(self,request,pk): book = Book.objects.filter(pk=pk).first() ser = BookSerializer1(instance=book) # 这里设置了主键值,单条记录many不需要写 return Response(ser.data) def delete(self,request,pk): res = Book.objects.filter(pk=pk).delete() print(res) # (1, {'app01.Book': 1}) # res是影响的行数 if res[0]>0: return Response({'code': 100, 'msg': '删除成功'}) else: return Response({'code': 103, 'msg': '要删除的数据不存在'}) # 反序列化修改 def put(self,request,pk): # 修改处理单条数据用过pk确定求改哪条数据 book = Book.objects.filter(pk=pk).first() # 序列化器类实例化需要传入instance,data才表示修改 ser = BookSerializer1(instance=book,data=request.data) if ser.is_valid(): # 重写update方法才能存入 ser.save() return Response(ser.data) return Response({'code':101,'msg':'校验未通过','error':ser.errors})path('books1/', views.BookView1.as_view()),path('books1/<int:pk>', views.BookDetailView1.as_view()),from django.db import modelsclass Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5,decimal_places=2) authors = models.CharField(max_length=32)from django.db import models# build four model tablesclass Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(decimal_places=2, max_digits=5) publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') def __str__(self): return self.name # 自定制字段 @property def publish_detail(self): return {'name': self.publish.name, 'addr': self.publish.city} @property def author_list(self): l = [] print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]> for author in self.authors.all(): print(author.author_detail) # AuthorDetail object (1) l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr}) return lclass Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE) def __str__(self): return self.name @property def authordetail_info(self): return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr}class AuthorDetail(models.Model): telephone = models.BigIntegerField() addr = models.CharField(max_length=64)class Publish(models.Model): name = models.CharField(max_length=32) city = models.CharField(max_length=32) email = models.EmailField()from app01 import modelsfrom rest_framework import serializers# 书序列化器class BookSerializer(serializers.ModelSerializer): class Meta: # 指定和哪个表有关系 model = models.Book # fields = '__all__' fields = ['id','name','price','publish','authors','publish_detail','author_list'] # 将关联表的信息全部取出来,不推荐使用 # depth = 1 extra_kwargs = { 'publish':{'write_only':True}, 'authors':{'write_only':True} }# 作者序列化器class AuthorSerializer(serializers.ModelSerializer): class Meta: # 指定和哪个表有关系 model = models.Author # fields = '__all__' fields = ['id', 'name', 'age', 'author_detail', 'authordetail_info'] extra_kwargs = { 'author_detail': {'write_only': True}, }# 作者详情序列化器class AuthorDetailSerializer(serializers.ModelSerializer): class Meta: # 指定和哪个表有关系 model = models.AuthorDetail fields = '__all__'# 出版社序列化器class PublishSerializer(serializers.ModelSerializer): class Meta: # 指定和哪个表有关系 model = models.Publish fields = '__all__'from rest_framework.response import Responsefrom rest_framework.views import APIViewfrom app01 import modelsfrom app01 import serializer# 书视图类class BookView(APIView): def get(self, requets): # 序列化 book_list = models.Book.objects.all() # 序列化多条数据many=True ser = serializer.BookSerializer(instance=book_list, many=True) return Response(ser.data) def post(self, request): # 获取反序列化数据 ser = serializer.BookSerializer(data=request.data) if ser.is_valid(): # 校验通过存入数据库,不需要重写create方法了 ser.save() return Response({'code': 100, 'msg': '新增成功', 'data': ser.data}) # 校验失败 return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})class BookViewDetail(APIView): def get(self, request, pk): book = models.Book.objects.filter(pk=pk).first() ser = serializer.BookSerializer(instance=book) return Response(ser.data) def put(self, request, pk): book = models.Book.objects.filter(pk=pk).first() # 修改,instance和data都要传 ser = serializer.BookSerializer(instance=book, data=request.data) if ser.is_valid(): # 校验通过修改,不需要重写update ser.save() return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data}) # 校验不通过 return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk): models.Book.objects.filter(pk=pk).delete() return Response({'code': 100, 'msg': '删除成功'})# 作者视图类class AuthorView(APIView): def get(self, requets): # 序列化 author_list = models.Author.objects.all() # 序列化多条数据many=True ser = serializer.AuthorSerializer(instance=author_list, many=True) return Response(ser.data) def post(self, request): # 获取反序列化数据 ser = serializer.AuthorSerializer(data=request.data) if ser.is_valid(): # 校验通过存入数据库,不需要重写create方法了 ser.save() return Response({'code': 100, 'msg': '新增成功', 'data': ser.data}) # 校验失败 return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})class AuthorViewDetail(APIView): def get(self, request, pk): book = models.Author.objects.filter(pk=pk).first() ser = serializer.AuthorSerializer(instance=book) return Response(ser.data) def put(self, request, pk): book = models.Author.objects.filter(pk=pk).first() # 修改,instance和data都要传 ser = serializer.AuthorSerializer(instance=book, data=request.data) if ser.is_valid(): # 校验通过修改,不需要重写update ser.save() return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data}) # 校验不通过 return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk): models.Author.objects.filter(pk=pk).delete() return Response({'code': 100, 'msg': '删除成功'})# 作者详情视图类class AuthorDetailView(APIView): def get(self, requets): # 序列化 author_list = models.AuthorDetail.objects.all() # 序列化多条数据many=True ser = serializer.AuthorDetailSerializer(instance=author_list, many=True) return Response(ser.data) def post(self, request): # 获取反序列化数据 ser = serializer.AuthorDetailSerializer(data=request.data) if ser.is_valid(): # 校验通过存入数据库,不需要重写create方法了 ser.save() return Response({'code': 100, 'msg': '新增成功', 'data': ser.data}) # 校验失败 return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})class OneAuthorViewDetail(APIView): def get(self, request, pk): book = models.AuthorDetail.objects.filter(pk=pk).first() ser = serializer.AuthorDetailSerializer(instance=book) return Response(ser.data) def put(self, request, pk): book = models.AuthorDetail.objects.filter(pk=pk).first() # 修改,instance和data都要传 ser = serializer.AuthorDetailSerializer(instance=book, data=request.data) if ser.is_valid(): # 校验通过修改,不需要重写update ser.save() return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data}) # 校验不通过 return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk): models.AuthorDetail.objects.filter(pk=pk).delete() return Response({'code': 100, 'msg': '删除成功'})# 出版社视图类class PublishView(APIView): def get(self, requets): # 序列化 author_list = models.Publish.objects.all() # 序列化多条数据many=True ser = serializer.PublishSerializer(instance=author_list, many=True) return Response(ser.data) def post(self, request): # 获取反序列化数据 ser = serializer.PublishSerializer(data=request.data) if ser.is_valid(): # 校验通过存入数据库,不需要重写create方法了 ser.save() return Response({'code': 100, 'msg': '新增成功', 'data': ser.data}) # 校验失败 return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})class PublishViewDetail(APIView): def get(self, request, pk): book = models.Publish.objects.filter(pk=pk).first() ser = serializer.PublishSerializer(instance=book) return Response(ser.data) def put(self, request, pk): book = models.Publish.objects.filter(pk=pk).first() # 修改,instance和data都要传 ser = serializer.PublishSerializer(instance=book, data=request.data) if ser.is_valid(): # 校验通过修改,不需要重写update ser.save() return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data}) # 校验不通过 return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors}) def delete(self, request, pk): models.Publish.objects.filter(pk=pk).delete() return Response({'code': 100, 'msg': '删除成功'})from django.contrib import adminfrom django.urls import pathfrom app01 import viewsurlpatterns = [ path('admin/', admin.site.urls), # 书 path('books/', views.BookView.as_view()), path('books/<int:pk>', views.BookViewDetail.as_view()), # 作者 path('authors/', views.AuthorView.as_view()), path('authors/<int:pk>', views.AuthorViewDetail.as_view()), # 作者详情 path('authorsdetail/', views.AuthorDetailView.as_view()), path('authorsdetail/<int:pk>', views.OneAuthorViewDetail.as_view()), # 出版社 path('publish/', views.PublishView.as_view()), path('publishdetail/<int:pk>', views.PublishViewDetail.as_view()),]
Postman自行测试,我测了测都能用,有问题望指正~