django之drf(部分讲解)
序列化类常用字段和字段参数
drf在Django字段类型的基础上派生了自己的字段类型以及字段参数- 序列化器的字段类型用于处理原始值和内部数据类型直接的转换
- 还可以用于验证输入、以及父对象检索和设置值
常用字段类
| 字段 | 字段构造方式 |
|---|---|
| BooleanField | BooleanField() |
| NullBooleanField | NullBooleanField() |
| CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
| EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
| RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
| SlugField | SlugField(max_length=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+ |
| URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
| UUIDField | UUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" |
| IPAddressField | IPAddressField(protocol=’both’, unpack_ipv4=False, **options) |
| IntegerField | IntegerField(max_value=None, min_value=None) |
| FloatField | FloatField(max_value=None, min_value=None) |
| DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
| DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
| DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
| TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
| DurationField | DurationField() |
| ChoiceField | ChoiceField(choices) choices与Django的用法相同 |
| MultipleChoiceField | MultipleChoiceField(choices) |
| FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
重要,后面讲
| 字段 | 字段构造方式 |
|---|---|
| ListField | ListField(child=, min_length=None, max_length=None) |
| DictField | DictField(child=) |
常用字段参数
选项参数
| 参数名称 | 说明 |
|---|---|
| max_length | 最大长度 |
| min_lenght | 最小长度 |
| allow_blank | 是否允许为空 |
| trim_whitespace | 是否截断空白字符 |
| max_value | 最小值 |
| min_value | 最大值 |
通用参数
| 参数名称 | 说明 |
|---|---|
| required | 表明该字段在反序列化时必须输入,默认True |
| default | 反序列化时使用的默认值 |
| allow_null | 表明该字段是否允许传入None,默认False |
| validators | 该字段使用的验证器 |
看一眼忘掉
| 参数名称 | 说明 |
|---|---|
| error_messages | 包含错误编号与错误信息的字典 |
| label | 用于HTML展示API页面时,显示的字段名称 |
| help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
重点
| 参数名称 | 说明 |
|---|---|
| read_only | 表明该字段仅用于序列化输出,默认False |
| write_only | 表明该字段仅用于反序列化输入,默认False |
反序列化校验执行流程
-1 先执行字段自己的校验规则----》最大长度,最小长度,是否为空,是否必填,最小数字。。。。
-2 validators=[方法,] ----》单独给这个字段加校验规则
name=serializers.CharField(validators=[方法,])
-3 局部钩子校验规则
-4 全局钩子校验规则
序列化高级用法之source
- 创建关联表
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) # 留住,还有很多
authors = models.ManyToManyField(to='Author')
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
phone = models.CharField(max_length=11)
- 迁移,录入数据
makemigrations
migrate
序列化定制字段名字
- 重点:source可以指定序列化字段的名字
-自有字段,直接写字段名字
-name_real = serializers.CharField(max_length=8, source='name')
-关联字段,一对多的关联,直接点
-publish = serializers.CharField(source='publish.name')
-多对多,搞不了,source不能用
-authors=serializers.CharField(source='authors.all')
- 序列化类
class BookSerializer(serializers.Serializer):
# 字段参数,通用的,所有字段都可以写 通过source指定哪个字段
# 自有字段,直接写字段名字
name_real = serializers.CharField(max_length=8, source='name')
real_price = serializers.CharField(source='price')
# 关联字段,一对多的关联,直接点
publish = serializers.CharField(source='publish.name')
#多对多,搞不了,source不能用
authors=serializers.CharField(source='authors.all')
序列化高级用法之定制字段的两种方式
方式一:SerializerMethodField定制
定制关联字段的显示形式
- 一对多的,显示字典
- 多对多,显示列表套字典
代码如下:
class BookSerializer(serializers.Serializer):
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 定制返回格式---》方式一
publish_detail = serializers.SerializerMethodField()
def get_publish_detail(self, obj):
return {'name': obj.publish.name, 'addr': obj.publish.addr}
author_list = serializers.SerializerMethodField()
def get_author_list(self, obj):
l = []
for author in obj.authors.all():
l.append({'name': author.name, 'phone': author.phone})
return l
在表模型中定制
表模型
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE) # 留住,还有很多
authors = models.ManyToManyField(to='Author')
def publish_detail(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
def author_list(self):
l = []
for author in self.authors.all():
l.append({'name': author.name, 'phone': author.phone})
return l
序列化类
class BookSerializer(serializers.Serializer):
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# publish_detail = serializers.CharField()
publish_detail = serializers.DictField()
author_list = serializers.ListField()
多表关联反序列化保存
新增图书接口
新增图书接口
前端传入的数据格式:{name:红楼梦,price:19,publish:1,authors:[1,2]}
视图类
class BookView(APIView):
def post(self, request):
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '新增成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
序列化类
class BookSerializer(serializers.Serializer):
# name和price 既用来序列化,又用来反序列化 即写又读 ,不用加read_only,write_only
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 只用来做序列化 只读 read_only
publish_detail = serializers.DictField(read_only=True)
author_list = serializers.ListField(read_only=True)
# 只用来做反序列化 只写 write_only
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True)
# 新增要重写create方法
def create(self, validated_data):
# validated_data 校验过后的数据,{name:红楼梦,price:19,publish:1,authors:[1,2]}
# 新增一本图书
book = Book.objects.create(name=validated_data.get('name'), price=validated_data.get('price'),
publish_id=validated_data.get('publish'))
# 作者也要关联上
# book.authors add remove set clear....
book.authors.add(*validated_data.get('authors'))
# book.authors.add(1,2)
return book
修改图书接口
新增图书接口
前端传入的数据格式:{name:红楼梦,price:19,publish:1,authors:[1,2]}
视图类
class BookDetailView(APIView):
def put(self, request, pk):
book = Book.objects.filter(pk=pk).first()
ser = BookSerializer(data=request.data, instance=book)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': '修改成功'})
else:
return Response({'code': 101, 'msg': ser.errors})
序列化类
# 反序列化的多表关联的保存
class BookSerializer(serializers.Serializer):
# name和price 既用来序列化,又用来反序列化 即写又读 ,不用加read_only,write_only
name = serializers.CharField(max_length=8)
price = serializers.CharField()
# 只用来做反序列化 只写 write_only
publish = serializers.CharField(write_only=True)
authors = serializers.ListField(write_only=True)
# 修改要重写update
def update(self, instance, validated_data):
# validated_data 校验过后的数据,{name:红楼梦,price:19,publish:1,authors:[1,2]}
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.publish_id = validated_data.get('publish')
# 先清空,再add
authors = validated_data.get('authors')
instance.authors.clear()
instance.authors.add(*authors)
instance.save()
return instance
反序列化字段校验其他
# 4层
-1 字段自己的:举例:name = serializers.CharField(max_length=8, error_messages={'max_length': '太长了'})
-2 validators=[方法,] 忽略掉
-3 局部钩子
-4 全局钩子
ModelSerializer使用
# ModelSerializer 继承自Serializer,帮咱们完成了很多操作
-跟表模型强关联
-大部分请求,不用写create和update了
# 如何使用
### ModelSerializer的使用
class BookSerializer(serializers.ModelSerializer):
# 跟表有关联
class Meta:
model = Book # 跟book表建立了关系 序列化类和表模型类
# fields = '__all__' # 序列化所有Book中的字段 id name price publish authors
fields = ['name', 'price', 'publish_detail', 'author_list', 'publish', 'authors'] # 序列化所有Book中的name和price字段字段
# 定制name反序列化时,最长不能超过8 给字段类加属性---方式一
extra_kwargs = {'name': {'max_length': 8},
'publish_detail': {'read_only': True},
'author_list': {'read_only': True},
'publish': {'write_only': True},
'authors': {'write_only': True},
}
# 如果Meta写了__all__ ,就相当于,复制了表模型中的所有字段,放在了这里,做了个映射
# name = serializers.CharField(max_length=32)
# price = serializers.CharField(max_length=32)
# 定制name反序列化时,最长不能超过8 给字段类加属性---方式二,重写name字段
# name = serializers.CharField(max_length=8)
# 同理,所有的read_only和wirte_only都可以通过重写或使用extra_kwargs传入
# 终极,把这个序列化类写成跟之前一模一样项目
# publish_detail = serializers.SerializerMethodField(read_only=True)
# def get_publish_detail(self, obj):
# return {'name': obj.publish.name, 'addr': obj.publish.addr}
# author_list = serializers.SerializerMethodField(read_only=True)
# def get_author_list(self, obj):
# l = []
# for author in obj.authors.all():
# l.append({'name': author.name, 'phone': author.phone})
# return l
# 局部钩子和全局钩子跟之前完全一样
def validate_name(self, name):
if name.startswith('sb'):
raise ValidationError('不能sb')
else:
return name
django之drf(部分讲解)的更多相关文章
- Django的DRF序列化方法
安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...
- 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...
- django框架-DRF工程之权限功能
1.相对于flask,原生而言django,DRF做的则更加的合理化,想要给予用户相应的权限,首先需要在settings中进行配置 REST_FRAMEWORK = { 'DEAFAULT_PERMI ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- Django和DRF的区别
Django和DRF的区别 一.Django REST Framwork 和 Django 1.两者的概念: Django REST Framwork: 将数据库的东西通过ORM的映射取出来,通过vi ...
- django框架之drf(部分讲解)
一.各个视图子类 两个视图基类 五个视图扩展类 九个视图子类----->视图类,不需要额外继承GenericAPIView,只需要继承九个州其中之一,就会有某个或某几个接口 路由 urlpatt ...
- [django]梳理drf知识点
要实现的功能 idc_list/ get 列出所有 post 创建一个idc idc_detail/1/ get 获取一个idc put 修改一个idc delete 删除一个idc 一般url是这样 ...
- django框架-DRF视图中的request和response
1.Request 相对于django框架,DRF工程的request类则是继承自HttpRequest类,Rest framework提供了parser解释器,用来解释请求中的content_typ ...
- Django RestFramework(DRF)类视图
基础视图 1.基础函数视图(@api_view) DRF提供了一种函数基础视图来装饰Django的普通视图,我们可以使用request来接受请求和response响应.一个小例子: from rest ...
随机推荐
- 报错的大怨种来了--java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
频繁爆出这样的错误:java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual t ...
- 2020 Multi-University Training Contest 1 . Fibonacci Sum 水题改编
题意很简单,就是让你求这个东西,这个时候你发现,原题???? https://blog.csdn.net/acdreamers/article/details/23039571 哦,只是原来写过的哪一 ...
- 如果您喜欢我的博客可以进行RSS订阅
如果喜欢我的博客,你也可以订阅我的博客 http://www.cnblogs.com/yhm138/rss 有时间的话我会写一篇菜鸟玩转RSS的介绍,或者你看这篇推送 2020-12-15填坑 我理解 ...
- 一个基于GPT模型实现的Git Commit信息自动生成工具
每次提交代码的时候,你是否有为如何写Commit Message而迟迟按不下提交的时刻呢?然后,死磨硬泡写了一些并提交后,又被review的小伙伴吐槽了呢?相信很多小伙伴有过这样的经历吧? 趁着最近C ...
- Go语言:编写一个 WebsiteRacer 的函数,用来对比请求两个 URL 来「比赛」,并返回先响应的 URL。如果两个 URL 在 10 秒内都未返回结果,返回一个 error。
问题: 你被要求编写一个叫做 WebsiteRacer 的函数,用来对比请求两个 URL 来「比赛」,并返回先响应的 URL.如果两个 URL 在 10 秒内都未返回结果,那么应该返回一个 error ...
- pack.json中的^ ~的区别
在版本说明前面还有个符号:'^'(插入符号)和'~'(波浪符号),他们之间的区别:例如: '~'(波浪符号):他会更新到当前minor version(也就是中间的那位数字)中最新的版本.放到我们的例 ...
- KMP算法的研究
前脚学后脚忘,是时候给自己通俗易懂的总结一下了 KMP是什么 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个字符串S内查找一个词W的出现位置.一个词在不 ...
- [VMware/CENOTS/Linux]VMware设置CentOS7共享文件夹[转载]
0 环境信息 VMWare: Linux CENTOS: 7.9.2009(Core) CPU: x86_64 / amd64 待共享的共享文件夹的物理路径: E:\VirtualMachine\sh ...
- CVE-2022-21454:漏洞整改mysql5.7.37升级至5.7.38 tar包升级
问题描述:对数据库服务器进行漏扫,发现一些中高位漏洞需要整改,有些数据库需要升级到最新版 漏洞修改指导链接:https://www.oracle.com/security-alerts/cpuapr2 ...
- 随手记:Redis 部署到linux上面后,本地无法连接
修改redis的配置文件 redis.conf 1. bind 设置为 0.0.0.0 2. protected-mode 设置为no (也就是关闭保护模式) 3. daemonize 设置 ...