drf序列化组件
Posted wangke0917
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf序列化组件相关的知识,希望对你有一定的参考价值。
rest_framework序列化之Serializer
步骤:
1.自定义一个类,继承Serializer类;
2.在类中写要序列化的字段;
3.使用:在views.py文件中,book_ser=BookSerializer(book_list,many=True),book_ser.data就是序列化后的数据。当序列化的数据有多条(为QuerySet对象)时设置many=True,当序列化的数据只有一条(为obj对象)时设置many=False。
models部分:
from django.db import models # Create your models here. class Book(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish = models.ForeignKey(to=‘Publish‘, null=True, on_delete=models.SET_NULL, db_constraint=False) author = models.ManyToManyField(to=‘Author‘, db_constraint=False) class Publish(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) address = models.CharField(max_length=16) class Author(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32) author_detail = models.OneToOneField(to=‘AuthorDetail‘, null=True, on_delete=models.SET_NULL, db_constraint=False) class AuthorDetail(models.Model): id = models.AutoField(primary_key=True) age = models.IntegerField() sex = models.SmallIntegerField(default=0) info = models.CharField(max_length=128)
views部分:
from rest_framework.views import APIView from rest_framework.response import Response from .models import * from django.shortcuts import HttpResponse from django.core import serializers from rest_framework import serializers class BookSerializers(serializers.Serializer): title=serializers.CharField(max_length=32) price=serializers.IntegerField() pub_date=serializers.DateField() publish=serializers.CharField(source="publish.name") #authors=serializers.CharField(source="authors.all") authors=serializers.SerializerMethodField() def get_authors(self,obj): temp=[] for author in obj.authors.all(): temp.append(author.name) return temp #此处可以继续用author的Serializers, # def get_authors(self,obj): # ret=obj.authors.all() # ss=AuthorSerializer(ret,many=True) # return ss.data class BookViewSet(APIView): def get(self,request,*args,**kwargs): book_list=Book.objects.all() # 序列化方式1: # from django.forms.models import model_to_dict # import json # data=[] # for obj in book_list: # data.append(model_to_dict(obj)) # print(data) # return HttpResponse("ok") # 序列化方式2: # data=serializers.serialize("json",book_list) # return HttpResponse(data) # 序列化方式3: bs=BookSerializers(book_list,many=True) #many=True代表有多条数据,如果只有一条数据,many=False return Response(bs.data) # 序列化方式4: # ret=models.Book.objects.all().values(‘nid‘,‘title‘) # dd=list(ret) # return HttpResponse(json.dumps(dd))
注:
1.source指定的如果是字段,则会显示字段,如果是方法,则会执行方法,不用加括号(books=serializers.CharField(source=‘books.all‘));
2.SerializerMethodField,必须配合方法使用 get_字段名(self,obj),obj是当前要序列化的对象;
3.SerializerMethodField对应的方法中还可以继续使用其他的序列化类。
rest_framework序列化之ModelSerializer
步骤:
1.自定义一个类继承ModelSerializer;
2.在类内部写:
class Meta: model=models.Book fields=‘__all__‘ # exclude=[‘name‘,‘price‘] depth=1
class BookSerializers(serializers.ModelSerializer): class Meta: model = models.Book # fields = "__all__" fields=[‘nid‘,‘title‘,‘authors‘,‘publish‘] # exclude=(‘nid‘,) #不能跟fields同时用 # depth = 1 #深度控制,写 几 往里拿几层,层数越多,响应越慢,官方建议0--10之间,个人建议最多3层 publish=serializers.SerializerMethodField() def get_publish(self,obj): return obj.publish.name authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=obj.authors.all() ss=AuthorSerializer(ret,many=True) return ss.data
请求数据校验和保存:
class BooksView(APIView): def post(self, request): response = {‘status‘: 200, ‘msg‘: ‘修改成功‘} try: obj_ser = self.BookSerializer(data=request.data) if obj_ser.is_valid(): # 校验 obj_ser.save() # 生成记录 response[‘data‘] = obj_ser.data else: response[‘msg‘] = obj_ser.errors except Exception as e: response[‘msg‘] = str(e) return Response(response)
校验字段局部和全局钩子函数:
class BookSerialzers(serializers.ModelSerializer): class Meta: model = models.Book fields = ‘__all__‘ depth = 1 #局部钩子函数,validate_字段名,value字段的值 def validate_name(self, value): if re.match(‘^[0-9]+‘, value): raise ValidationError(‘书名不能以数字开头‘) return value #全局钩子函数,对全局字段进行校验 def validate(self,objdict): name=objdict.get(‘name‘) price=objdict.get(‘price‘) if name != price: raise ValidationError(‘错了‘) else: return objdict
以上是关于drf序列化组件的主要内容,如果未能解决你的问题,请参考以下文章