「Django」rest_framework学习系列-序列化
序列化
方式一 :在业务类里序列化数据库数据
- class RolesView(APIView):
- def get(self,request,*args,**kwargs):
- roles = models.Role.objects.all().values('id','title')[1:3]
- ret = list(roles)
- r = json.dumps(ret,ensure_ascii=False)
- return HttpResponse(r)
方式二:写个序列化的类,在业务类中引用,序列化类中可以定制字段
- class UserinfoSerializer(serializers.ModelSerializer):
- #字段名与数据库相同则替换,不同则添加
- type = serializers.CharField(source='get_usertype_display')
- gb = serializers.CharField(source='group.title')
- class Meta:
- model = models.UserInfo
- #全部显示
- fields = '__all__'
- #定制显示
- # fields = ['id','username','type','gb']
定制类
- class UserInfo(models.Model):
- usertype_choices = (
- (1,'普通用户'),
- (2,'VIP用户'),
- (3,'SVIP用户')
- )
- usertype = models.IntegerField(choices=usertype_choices,verbose_name='用户类型')
- username = models.CharField(max_length=32,unique=True,verbose_name='用户名')
- password = models.CharField(max_length=64,verbose_name='密码')
- group = models.ForeignKey('UserGroup',on_delete=models.DO_NOTHING,verbose_name='分组')
- roles = models.ManyToManyField('Role',verbose_name='职业')
- class Meta:
- verbose_name = '用户管理'
- verbose_name_plural = verbose_name
- def __str__(self):
- return self.username
对应数据库结构
- class UserInfoView(APIView):
- authentication_classes = []
- permission_classes = []
- def get(self,request,*args,**kwargs):
- m = models.UserInfo.objects.all()
- ser = UserinfoSerializer(instance=m,many=True)
- #单表的话这里many = false
- return Response(ser.data)
业务类
方式二补充:source不适合many to many,many to many需要自定义显示
- role = serializers.SerializerMethodField() #自定义显示
- def get_role(self,row):
- role_list = row.roles.all()
- ret = []
- for item in role_list:
- ret.append({'id':item.id,'title':item.title})
- return ret
many to many
方式三:depth根本连表结构往深层取值
- class UserinfoSerializer(serializers.ModelSerializer):
- usertype = serializers.CharField(source='get_usertype_display')
- class Meta:
- model = models.UserInfo
- #全部显示
- fields = '__all__'
- depth = 1 #0~10之间
- #定制显示
- # fields = ['id','username','type','gb']
定制类
- [{"id": 1, "usertype": 1, "username": "wrx", "password": "", "group": {"id": 1, "title": "A组"}, "roles": [{"id": 2, "title": "老师"}, {"id": 3, "title": "医生"}]},
- {"id": 2, "usertype": 2, "username": "ylp", "password": "", "group": {"id": 2, "title": "B组"}, "roles": [{"id": 3, "title": "医生"}]}]
取值结果
方式四:生成链接,即把上述类的group生成链接
- class UserinfoSerializer(serializers.ModelSerializer):
- usertype = serializers.CharField(source='get_usertype_display')
- group = serializers.HyperlinkedIdentityField(view_name='grp',lookup_field='group_id',lookup_url_kwarg='pk')
- #name,pk值对应urls中的re-path
- class Meta:
- model = models.UserInfo
- #全部显示
- fields = '__all__'
- depth = 1 #0~10之间
- #定制显示
- # fields = ['id','username','type','gb']
定制类
- re_path(r'^(?P<version>[v1|v2]+)/group/(?P<pk>\d+)$',GroupView.as_view(),name='grp')
PS:这里经历了一个错误,如果配置了全局的版本控制(详见版本控制配置),这里要也要配置,否则会一直报错
django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "grp". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
- class UserInfoView(APIView):
- def get(self,request,*args,**kwargs):
- m = models.UserInfo.objects.all()
- ser = UserinfoSerializer(instance=m,many=True,context={'request':request})
- return Response(ser.data)
Views业务类
PS:实例这个定制类的时候要加要加context={'request':request}
实际调用的是另一个views类的url
- class GroupSerializer(serializers.ModelSerializer):
- class Meta:
- model = models.UserGroup
- fields = '__all__'
- class GroupView(APIView):
- def get(self,request,*args,**kwargs):
- pk = kwargs.get('pk')
- obj = models.UserGroup.objects.filter(pk=pk).first()
- ser = GroupSerializer(instance=obj, many=False)
- t = json.dumps(ser.data, ensure_ascii=False)
- return HttpResponse(t)
上面re_path对应的定制类和业务类
方式五:三张表互相关联的反向查找
- class Course(models.Model):
- title = models.CharField(max_length=32,verbose_name='课程名称')
- course_img = models.ImageField(verbose_name='课程图片',upload_to = "static/img/")
- course_choice = (
- (0, '入门级'),
- (1, '普通难度'),
- (2, '中等难度'),
- (3, '高级难度'),
- )
- level = models.IntegerField(verbose_name='课程难度',choices=course_choice,default=0)
- class Meta:
- verbose_name = '课程管理'
- verbose_name_plural = verbose_name
- def __str__(self):
- return self.title
- class CourseInfo(models.Model):
- why = models.CharField(verbose_name='课程描述',max_length=255)
- course = models.OneToOneField(to='Course',on_delete=models.DO_NOTHING,verbose_name='关联课程')
- recommend_course = models.ManyToManyField(to='Course',verbose_name='推荐课程',related_name='rc')
- class Meta:
- verbose_name = '课程详细'
- verbose_name_plural = verbose_name
- def __str__(self):
- return '课程详细:'+self.course.title
- class Section(models.Model):
- num = models.IntegerField(verbose_name='章节')
- name = models.CharField(max_length=64,verbose_name='课程章节')
- course = models.ForeignKey(to='Course', on_delete=models.DO_NOTHING, verbose_name='关联课程')
- class Meta:
- verbose_name = '课程章节'
- verbose_name_plural = verbose_name
- def __str__(self):
- return '课程章节'+self.course.title
表结构
PS:第二张表与第一张表多对多并且单对单(这里有个小知识点,同时多对多和单对单的时候有一张表要加related_name='rc'),第三张表与第一张表一对多,需求:通过序列化第二张表得到第一张表和第三张表的相关内容
- class CourseinfoSerializer(serializers.ModelSerializer):
- #单对单,单对多,choice可以用这种方式,多对多不能使用
- title = serializers.CharField(source='course.title')
- level = serializers.CharField(source='course.get_level_display')
- #多对多需要自定义
- recommends = serializers.SerializerMethodField()
- def get_recommends(self, row):
- role_list = row.recommend_course.all()
- ret = []
- for item in role_list:
- ret.append({'id': item.id, 'title': item.title})
- return ret
- #3张表互相关联的反向查找
- sections = serializers.SerializerMethodField()
- def get_sections(self, row):
- role_list = row.course.section_set.all()
- ret = []
- for item in role_list:
- ret.append({'num': item.num, 'name': item.name})
- return ret
- class Meta:
- model = models.CourseInfo
- # fields = '__all__'
- fields = ['id','title','level','why','recommends','sections']
- # depth = 2
定制类
- def retrieve(self,request, *args, **kwargs):
- ret = {'code': 1000, 'data': None}
- pk = kwargs.get('pk')
- try:
- obj = models.CourseInfo.objects.filter(course_id=pk)
- ser = sl.CourseinfoSerializer(instance=obj, many=True)
- ret['data'] = ser.data
- except Exception as e:
- ret['code'] = 1001
- ret['error'] = '获取课程失败'
- return Response(ret)
业务类
PS:这实际是个类的get请求,re_path(r'^course/(?P<pk>\d+)$',views.CourseView.as_view({'get':'retrieve'})),
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
序列化-数据验证,验证title数据不能为空且必须以wrx开头
- class UserGroupSerializer(serializers.Serializer):
- title = serializers.CharField(error_messages={'required':'标题不能为空'},)
- def validate_title(self,value):
- if not value.startswith('wrx'):
- message = '标题必须以%s开头'%'wrx'
- raise exceptions.ValidationError(message)
- else:
- return value
定制类
- class UserGroupView(APIView):
- def post(self,request,*args,**kwargs):
- src = ''
- res = UserGroupSerializer(data=request.data)
- if res.is_valid():
- print(res.validated_data)
- src = str(res.validated_data['title'])
- else:
- print(res.errors)
- src = str(res.errors)
- return HttpResponse(src)
业务类
「Django」rest_framework学习系列-序列化的更多相关文章
- 「Django」rest_framework学习系列-分页
分页a.分页,看第N页,每页显示N条数据方式一:使用PageNumberPagination创建分页对象,配合settings全局配置 views设置 from rest_framework.pagi ...
- 「Django」rest_framework学习系列-视图
方式一 1.settings设置 INSTALLED_APPS = [ ... 'rest_framework', ] 2.views设置 from rest_framework.response i ...
- 「Django」rest_framework学习系列-API访问跨域问题
#以中间件方式解决API数据访问跨域问题1.API下新建文件夹下写PY文件a.引入内置类继承: from django.middleware.common import MiddlewareMixin ...
- 「Django」rest_framework学习系列-路由
自动生成4个url路由:from rest_framework import routersrouter = routers.DefaultRouter()router.register(r'wrx' ...
- 「Django」rest_framework学习系列-渲染器
渲染器:作用于页面,JSONRenderer只是JSON格式,BrowsableAPIRenderer有页面,.AdminRenderer页面以admin形式呈现(需要在请求地址后缀添加?fromat ...
- 「Django」rest_framework学习系列-解析器
满足两个要求,request.Post中才有值 1.请求头要求:请求头中的Content-Type为application/x-www-form-urlencoded 2.数据格式要求 name=x& ...
- 「Django」rest_framework学习系列-版本认证
1.自己写: class UserView(APIView): versioning_class = ParamVersion def get(self,request,*args,**kwargs) ...
- 「Django」rest_framework学习系列-权限认证
权限认证:1.项目下utils文件写permissions.py文件 from rest_framework.permissions import BasePermission class SVIPP ...
- 「Django」rest_framework学习系列-节流控制
1.节流自定义类: import time from api import models VISIT_RECORD = {} class VisitThrottle(BaseThrottle): #设 ...
随机推荐
- Variable() placeholder() constant() 的区别
转载来自: http://www.studyai.com/article/33e22cef42274e8a
- content-length与Transfer-Encoding: chunked的问题释疑
http返回头中content-length与Transfer-Encoding: chunked的问题释疑 先说说问题出现的背景: 公司服务器与手机客户端交互,客户端请求一个动态生成的XML文件,在 ...
- Java线上应用故障排查之一:高CPU占用 (转)
一个应用占用CPU很高,除了确实是计算密集型应用之外,通常原因都是出现了死循环. (友情提示:本博文章欢迎转载,但请注明出处:hankchen,http://www.blogjava.net/hank ...
- LeetCode 206. Reverse Linked List(C++)
题目: Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5->4 ...
- 2018-2019-20172321 《Java软件结构与数据结构》第五周学习总结
2018-2019-20172321 <Java软件结构与数据结构>第五周学习总结 教材学习内容总结 第9章 排序与查找 9.1查找 查找是这样一个过程,即在某个项目组中寻找某一指定目标元 ...
- 软工1816 · Alpha冲刺(6/10)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 alpha冲刺时间延后一周,重新规划任务安排 完成食堂店铺经纬度标注,以供美食 ...
- 福大软工1816:Beta(3/7)
Beta 冲刺 (3/7) 队名:第三视角 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务 文字/口头描述 参与开发关键词提醒部分 展示GitHu ...
- HDU 5172 GTY's gay friends 线段树+前缀和+全排列
题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5172 bc(中文):http://bestcoder.hdu.edu.cn/contest ...
- C语言调查问卷
1.你对自己的未来有什么规划?做了哪些准备?毕业后应该不会从事编程类工作,目前有在学习感兴趣的东西.2.你认为什么是学习?学习有什么用?现在学习动力如何?为什么?学习就是把不懂变成懂,可以充实自己.没 ...
- Java中的网络编程-2
Socket编程:(一般的网络编程) <1> 两个 JAVA 应用程序可通过一个双向的网络通信连接, 实现数据交换, 这个双向链路的一段称为一个 Socket. <2> Soc ...