Django Rest Framework 序列化接口(GET与POST)设计 (前期版)!
定义序列化器(本质就是一个类),一般包括模型类的字段,有自己的字段类型规则。实现了序列化器后,就可以创建序列化对象以及查询集进行序列化操作,通过序列化对象.data来获取数据(不用自己构造字典,再返回Json数据)
创建一个django项目;
创建一个app,且名字为:books
1 INSTALLED_APPS = [ 2 'django.contrib.admin', 3 'django.contrib.auth', 4 'django.contrib.contenttypes', 5 'django.contrib.sessions', 6 'django.contrib.messages', 7 'django.contrib.staticfiles', 8 'books', 9 'rest_framework' 10 ]
from django.contrib import admin from django.urls import path from books import views urlpatterns = [ path('admin/', admin.site.urls), path('book/',views.BookView.as_view()) ]
from django.shortcuts import render, HttpResponse from . import models # 1.原生django序列化组件使用 from django.views import View from django.core.serializers import serialize # 1.Django原生序列化的使用 # class BookView(View): # def get(self, request): # # 获取queryset # book_list = Book.objects.all() # # 对queryset进行序列化 # serialize_data = serialize('json', book_list) # # 返回序列化后的数据 # return HttpResponse(serialize_data) # 2.1-DRF序列化组件使用 from rest_framework.views import APIView from rest_framework.response import Response # 在应用下新建一个文件:serizlizer.py 用来写相关需要序列化的数据 # 导入serizlizer.py文件下的:BookSerizlizer类 from .serizlizer import BookSerizlizer class BookView(APIView): def get(self, request): # 拿到书的对象数据 book_obj = models.Book.objects.all() # 创造一个序列化器,传入书对象数据。 serialized_data = BookSerizlizer(book_obj, many=True) # 返回DRF序列化后的数据.最后需要点data才能拿到结果 return Response(serialized_data.data) # 访问127.0.0.1:8000/books/==>以下为页面拿到的数据(authors字段不正常, # 因为authors在数据库与book表是多对多字段, # 所以在serizlizer.py里面def一个方法来获取这项数据) ''' [ { "nid": "1", "title": "python初级", "price": "188.00", "publish": "清华大学出版社", "authors": "serializer.Author.None" }, { "nid": "2", "title": "python中级", "price": "78.00", "publish": "清华大学出版社", "authors": "serializer.Author.None" }, ] ''' def post(self, request): '''通过序列化组件进行post接口(提交一条数据)设计,步骤如下: - 定义post方法:在视图类中定义post方法; - 开始序列化:通过上面定义的序列化类,创建一个序列化对象,传入参数data=request.data(application/json)数据; - 校验数据:通过实例对象的is_valid()方法,对请求数据的合法性进行校验; - 保存数据:调用save()方法,将数据插入数据库; - 插入数据到多对多关系表:如果有多对多字段,手动插入数据到多对多关系表; - 返回:将插入的对象返回; ''' serialized_data = BookSerizlizer(data=request.data) if serialized_data.is_valid(): book = serialized_data.save() # 手动绑定多对多关系,也可以放到create方法中去 authors = models.Author.objects.filter(nid__in=request.data['authors']) book.authors.add(*authors) return Response(serialized_data.data) else: return Response(serialized_data.errors) '''分析:上面这种方法有两个问题:一个是需要手动插入数据(写序列化类中写create方法), 另一个是如果字段很多,写序列化类的字段也会变成一种负担,那么有没有更简单的方式呢?当然, 那就是用ModelSerializer!所以我们需要修改一下serializer.py中的代码'''
from django.db import models # Create your models here. class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to='Publish', related_name='book', on_delete=models.CASCADE) authors = models.ManyToManyField(to='Author') 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() def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() def __str__(self): return self.name
# 2.1-导入序列化模块.创造一个序列化数据的类 from rest_framework import serializers #一版本的序列化类 # class BookSerizlizer(serializers.Serializer): # nid = serializers.CharField(max_length=32) # title = serializers.CharField(max_length=128) # price = serializers.IntegerField() # publish = serializers.CharField(max_length=32) # # authors = serializers.CharField(max_length=32)#authors为多对多字段,应该使用下面的方法 # authors = serializers.SerializerMethodField() # # # 定义一个方法获取多对多字段数据,注意:get_必须与字段字段名称一致,否则报错。,并传入一个book对象 # def get_authors(self, book_obj): # authors = [] # # book_obj.authors.all()拿到每本书对应的作者(比如:models.Book.objects.first().authors.all()拿到第一本书的作者) # for author in book_obj.authors.all(): # # 把作者的名字添加进去,(author.name) # authors.append(author.name) # return authors #关于POST接口需要重新写一下BookSerizlizer类 '''注意:因为多对多关系字段是我们自定义的,而且必须这样定义,返回的数据才有意义, 而用户插入数据的时候,无法找到这个字段类型SerializerMethodField, 所以,序列化类不能帮我们插入数据到多对多表,我们必须手动插入数据,!!!以上序列化类注释不用了!!!因此序列化类要做如下修改:''' #二版本序列化类 # from .models import Book # # class BookSerizlizer(serializers.Serializer): # # nid字段只需要传给客户端,用户提交不需要id,所以read_only=True # nid = serializers.CharField(read_only=True, max_length=32) # title = serializers.CharField(max_length=128) # price = serializers.DecimalField(max_digits=5, decimal_places=2) # publish = serializers.CharField(max_length=32) # # SerializerMethodField默认read_only=True # authors = serializers.SerializerMethodField() # # # 定义一个方法获取多对多字段数据,注意:get_必须与字段字段名称一致,否则报错。,并传入一个book对象 # def get_authors(self, book_obj): # authors = [] # # book_obj.authors.all()拿到每本书对应的作者(比如:models.Book.objects.first().authors.all()拿到第一本书的作者) # for author in book_obj.authors.all(): # # 把作者的名字添加进去,(author.name) # authors.append(author.name) # return authors # # # 必须手动插入数据,因此post方法提交数据必须有create方法! # def create(self, validated_data): # print(validated_data) # validated_data为过滤之后的数据 # validated_data['publish_id'] = validated_data.pop('publish') # book = Book.objects.create(**validated_data) # # return book #三版本序列化类 from . import models #使用ModelSerializer,post方法就不再依赖create方法 class BookSerizlizer(serializers.ModelSerializer): class Meta: model = models.Book fields = ( 'title', 'price', 'publish', 'authors', 'author_list', 'pubName', 'pubCity' ) extra_kwargs = { 'publish':{'write_only':True}, 'authors':{'write_only':True} } pubName = serializers.CharField(max_length=32, read_only=True, source='publish.name') pubCity = serializers.CharField(max_length=32, read_only=True, source='publish.city') # 多对多字段 author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): authors = list() for author in book_obj.authors.all(): authors.append(author.name) return authors