DRF之序列化
程序员文章站
2022-07-12 11:17:37
...
-
一、restframework 序列化组件之
serializers
from rest_framework import serializers from rest_framework.response import Response from rest_framework.views import APIView from app01.models import Book class BookSerializer(serializers.Serializer): # 【自定义一个序列化类】 title = serializers.CharField(max_length=32) # 【写哪些字段就序列化哪些】 price = serializers.DecimalField(max_digits=5, decimal_places=2) publish = serializers.CharField(max_length=32) # 一本书对应一个出版社 publish_email = serializers.CharField(max_length=32, source='publish.email') # 一本书对应一个出版社 publish_city = serializers.CharField(max_length=32, source='publish.city') # 一本书对应一个出版社 # authors = serializers.CharField(max_length=32) # authors = serializers.CharField(max_length=32,source='authors.all') # "authors": "<QuerySet [<Author: 张三>, <Author: 王五>]>" authors = serializers.SerializerMethodField() def get_authors(self, obj): ret = [] # 这个数据类型可根据前端需求自己构建 for i in obj.authors.all(): ret.append(i.name) return ret class BookView(APIView): def get(self, request): book_list = Book.objects.all() bs = BookSerializer(book_list, many=True) # 【序列化接口】 print(bs.data) # 【有序字典】 return Response(bs.data) def post(self,request): # 请求来了必须先校验有效性,才能存入数据库 bs =BookSerializer(data=request.data) print(request.data) # 【字典】 print(bs.is_valid()) # 不符合规范就是False if bs.is_valid(): # 【校验】 Book.objects.create(**request.data) # 【存库】 return Response(bs.data) # 【返回结果】 else: return Response(bs.errors) # 【返回错误信息】
这样写非常多,每一个字段都得自己写,所以就引出了
ModelSerializer
,【见 三】 -
二、序列化过程(GET请求)
bs = BookSerializer(book_list,many = True) bs.data temp = [] for obj in book_list: temp.append({ 'title':obj.title, 'price':obj.price, 'publish':obj.publish 【此时,取出来的是个对象,显示的是此对象中__str__方法的返回值】 所以,设置外键关联的字段也能序列化出来。 }) 1,另外:加上source,就会找source里面的。可用到外键的关联字段里,点出来一个对象之后再找出对象的属性。 publish = serializers.CharField(max_length=32,source='publish.email') 2,所以:外键的关联对象的任何字段都可以取出。 publish_email = serializers.CharField(max_length=32,source='publish.email') publish_city = serializers.CharField(max_length=32,source='publish.city') 3,多对多字段这样写会形成这样的数据类型: authors = serializers.CharField(max_length=32,source='authors.all') "authors": "<QuerySet [<Author: 张三>, <Author: 王五>]>" 4,所以:多对多字段可以这样写: authors = serializers,SerializerMethodField() def get_authors(self,obj): ret = [] for i in obj.authors.all() ret.append(i.name) return ret 5,序列化时,看见是SerializerMethodField类,就会执行自定义的get_字段名的方法。即可解决多对多的显示问题 if 字段SerializerMethodField: "authors":get_authors(obj)
-
三、
ModelSerializer
的(get查看)和(post添加)from rest_framework import serializers from rest_framework.response import Response from rest_framework.views import APIView from app01.models import Book class BookSerializer(serializers.ModelSerializer): publish_name = serializers.CharField(max_length=32, source="publish.name", read_only=True) publish_city = serializers.CharField(max_length=32, source='publish.city',read_only=True) publish_pk=serializers.CharField(max_length=32,source="publish.pk",read_only=True) author_list = serializers.SerializerMethodField(read_only=True) # 【规定只读】 def get_author_list(self, obj): ret = [] # 这个数据类型可根据前端需求自己构建 for i in obj.authors.all(): ret.append({'name':i.name,'pk':i.pk}) return ret publish_info = serializers.SerializerMethodField(read_only=True) def get_publish_info(self, obj): return {"name": obj.publish.name, "publish_pk": obj.publish.pk,"publish_city":obj.publish.city} class Meta: model = Book # fields = ['title','price'] fields = '__all__' extra_kwargs = {"publish": {"write_only": True}, "authors": {"write_only": True}}#【规定只写】 class BookView(APIView): def get(self, request): book_list = Book.objects.all() bs = BookSerializer(book_list, many=True) return Response(bs.data) def post(self, request): bs = BookSerializer(data=request.data, many=False) if bs.is_valid(): bs.save() # 【create操作,用ModelSerializer就可直接save】 return Response(bs.data) else: return Response(bs.errors)
转载于:https://www.jianshu.com/p/9e365c856fcd
上一篇: 进程信号的捕捉
下一篇: Liunx之信号捕捉与模拟sleep函数