$Django Rest Framework-序列化组件
1 序列化组件
e=serializers.SerializerMethodField()
# 方法名:叫get_字段名, 参数,返回字典
def get_e(self,obj): #obj为book对象
from app01 import models from rest_framework import serializers from rest_framework.serializers import Serializer,ModelSerializer from django.http import JsonResponse class auth(Serializer): name=serializers.CharField() age=serializers.CharField() #方式1 class ser(Serializer): #*****如果不指定source,字段必须对应起来,如果指定了source,字段可以任意命名 a=serializers.CharField(source='name') #source 可以指定字段,也可也指定方法 b=serializers.CharField(source='authors') c=serializers.CharField(source='publish.name') d=serializers.CharField(source='publish.test') e=serializers.SerializerMethodField() # 方法名:叫get_字段名,要传参数,参数是:当前book对象 def get_e(self,obj): #obj为book对象 # for循环 # li=[{'name':i.name,'age':i.age} for i in obj.authors.all()] # return li #序列化 auths=obj.authors.all() li=auth(auths,many=True) return li.data #方式2 class ser1(ModelSerializer): class Meta: model=models.Book fields='__all__' # fields=['name','price'] # exclude=['authors'] depth=10 #深度为1 当前模型字段 为2跨1个表的字段 #cbv视图 class show(APIView): def get(self,request): #drf books=models.Book.objects.all() bb=ser1(instance=books,many=True) #queryset对象/也可以是多单个对象|||many指定单个多个 print(bb.data) #json格式dic return JsonResponse(bb.data,safe=False) #django自带的 # from django.core import serializers # books=models.Book.objects.all() # ret=serializers.serialize('json',books) # print(ret,type(ret)) #json格式str # dic = {'data': ret} # return HttpResponse(ret)
2 序列化组件
①前台url请求数据:
HyperlinkedIdentityField 返回一个数据带链接 写在继承Serializer的类中(很少用)
*3个参数以及scontext={'request':request} #拼了一条路由
class Ser_link(Serializer): name=serializers.CharField(max_length=32,error_messages={'max_length':'最长32位'}) #get请求时Ser_link(books,many=True,context={'request':request}) 域名 #参1:路由别名 参2:字段 参3:有名分组名 publish = serializers.HyperlinkedIdentityField (view_name='aaa', lookup_field='publish_id', lookup_url_kwarg='id') class Books(APIView): def get(self,request): books=models.Book.objects.all() ser=Ser_link(books,many=True,context={'request':request}) return JsonResponse(ser.data,safe=False)
url(r'^books/$', views.Books.as_view()), url(r'^publish/(?P<id>\d+)$', views.Publish.as_view(),name='aaa') #http://127.0.0.1/publish/1
②前台传数据到后台:
0直接调save()保存更新的话,(必须继承ModelSerializer)
1.数据校验(与form组件类似有error_messages,局部钩子等) 2.数据保存/更新(传instance和不传instance的区别# 不传instance,调save(),往数据库新增数据# 传instance,调save(),修改数据,)
class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' name = serializers.CharField(min_length=2, error_messages={'required': '该字段必填'}) authors = serializers.CharField(required=False) # 局部钩子: def validate_name(self, value): # print(value) if value.startswith('sb'): # 不能以sb开头 raise ValidationError('不能以sb开头') else: return value # 全局钩子找到了 def validate(self, value): # value是所有校验通过数据的字典 print(value) name = value.get('name') price = value.get('price') if name and price: if str(name) == str(price): return value else: raise ValidationError('名字跟价格不相等') return value class BooksDetail(APIView): authentication_classes = [Auth, ] def get(self, request, pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() # 生成一个序列化的对象,传参数 # 序列化单,记住many=False if ret: book_ser = BookSerializer(ret, many=False) print(book_ser.data) response['data'] = book_ser.data else: response['status'] = 101 response['msg'] = '您查询的不存在' return JsonResponse(response, safe=False) def put(self, request, pk): response = {'status': 100, 'msg': '成功'} ret = models.Book.objects.all().filter(pk=pk).first() if ret: # 数据校验 # 传instance和不传instance,传instance的区别 # 不传instance,调save(),往数据库新增数据 # 传instance,调save(),修改数据 ser = BookSerializer(data=request.data, instance=ret) if ser.is_valid(): # ret.name=request.data.get('name') ser.save() else: response['status'] = 101 response['msg'] = ser.errors else: response['status'] = 102 response['msg'] = '修改的对象不存在' return JsonResponse(response, safe=False)
url(r'^books/(?P<pk>\d+)$', views.Books_xx.as_view()),