「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): #设 ...
随机推荐
- PReLU——Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
1. 摘要 在 \(ReLU\) 的基础上作者提出了 \(PReLU\),在几乎没有增加额外参数的前提下既可以提升模型的拟合能力,又能减小过拟合风险. 针对 \(ReLU/PReLU\) 的矫正非线性 ...
- 【RL系列】SARSA算法的基本结构
SARSA算法严格上来说,是TD(0)关于状态动作函数估计的on-policy形式,所以其基本架构与TD的$v_{\pi}$估计算法(on-policy)并无太大区别,所以这里就不再单独阐述之.本文主 ...
- Fedora 26/27/28网易云音乐安装
信息从 https://www.southcity-oldboy.com/1474.html获取,感谢站长南城旧少年! 以下为前辈网页上的内容 1.安装 RPM Fusion 源 (free): ht ...
- Hibernate查询的六种方式
Hibernate查询的六种方式 分别是HQL查询,对象化查询Criteria方法,动态查询DetachedCriteria,例子查询,sql查询,命名查询. 如果单纯的使用hibernate ...
- 根据Unicode码生成汉字
最近需要一批汉字字符数据,类似数字字符与ASCII码之间的对应关系,汉字字符与Unicode码之间也存在对应关系. 所以可以遍历Unicode码批量生成汉字. 其中,汉字为宽字符,输出时候注意需要修改 ...
- 使用git提交代码的一些小心得
1.不进行push不能运行的代码,如果需要提交,可以先注释,保证其他人pull时,可以得到能够正常使用的代码 2.每做完一件事,写一条描述,一次提交.不要等写了一堆代码,然后写一堆描述,这样如果需要查 ...
- 1st 四人小组项目
小组名称:好好学习 项目组长:林莉 组员:王东涵.宫丽君.胡丽娜 项目选题:基于jsp的车库管理系统 项目期限:十周内<暂定> 需求分析:有待进一步思考
- 剖析Vue原理&实现双向绑定MVVM-1
本文能帮你做什么?1.了解vue的双向数据绑定原理以及核心代码模块2.缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,相对较简陋,并未考 ...
- C#和Java访问修饰符的比较
访问修饰符对于C#:类 的默认修饰符是 internal(外部类只能被public / internal 修饰)枚举 的默认修饰符是 public 且此类型不允许其它访问修饰符接口 的默认修饰符是 i ...
- lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现
ReentrantLock的实现是基于其内部类FairSync(公平锁)和NonFairSync(非公平锁)实现的. 其可重入性是基于Thread.currentThread()实现的: 如果当前线程 ...