网站备案信息找回,谁有手机网站,中国建工社微课程官网,毕业设计做网站答辩本文从分析现在流行的前后端分离Web应用模式说起#xff0c;然后介绍如何设计REST API#xff0c;通过使用Django来实现一个REST API为例#xff0c;明确后端开发REST API要做的最核心工作#xff0c;然后介绍Django REST framework能帮助我们简化开发REST API的工作。
全…
本文从分析现在流行的前后端分离Web应用模式说起然后介绍如何设计REST API通过使用Django来实现一个REST API为例明确后端开发REST API要做的最核心工作然后介绍Django REST framework能帮助我们简化开发REST API的工作。
全套笔记直接地址 请移步这里 共 5 章24 子模块 DRF工程搭建
见识DRF的魅力
我们仍以在学习Django框架时使用的图书英雄为案例使用Django REST framework快速实现图书的REST API。
1. 创建序列化器
在booktest应用中新建serializers.py用于保存该应用的序列化器。
创建一个BookInfoSerializer用于序列化与反序列化。
class BookInfoSerializer(serializers.ModelSerializer):图书数据序列化器class Meta:model BookInfofields __all__model 指明该序列化器处理的数据字段从模型类BookInfo参考生成fields 指明该序列化器包含模型类中的哪些字段all’指明包含所有字段
2. 编写视图
在booktest应用的views.py中创建视图BookInfoViewSet这是一个视图集合。
from rest_framework.viewsets import ModelViewSet
from .serializers import BookInfoSerializer
from .models import BookInfoclass BookInfoViewSet(ModelViewSet):queryset BookInfo.objects.all()serializer_class BookInfoSerializerqueryset 指明该视图集在查询数据时使用的查询集serializer_class 指明该视图在进行序列化或反序列化时使用的序列化器
3. 定义路由
在booktest应用的urls.py中定义路由信息。
from . import views
from rest_framework.routers import DefaultRouterurlpatterns [...
]router DefaultRouter() # 可以处理视图的路由器
router.register(books, views.BookInfoViewSet, namebooks) # 向路由器中注册视图集urlpatterns router.urls # 将路由器中的所以路由信息追到到django的路由列表中4. 运行测试
运行当前程序与运行Django一样
python manage.py runserver在浏览器中输入网址127.0.0.1:8000可以看到DRF提供的API Web浏览页面 1点击链接127.0.0.1:8000/books/ 可以访问所有数据的接口呈现如下页面 2在页面底下表单部分填写图书信息可以访问添加新图书的接口保存新书 点击POST后返回如下页面信息 3在浏览器中输入网址127.0.0.1:8000/books/1/可以访问单一图书信息的接口id为1的图书呈现如下页面 4在页面底部表单中填写图书信息可以访问修改图书的接口 点击PUT返回如下页面信息 5点击DELETE按钮可以访问删除图书的接口 返回如下页面 至此是不是发现Django REST framework很好用
Serializer序列化器
序列化器的作用
进行数据的校验对数据对象进行转换
定义Serializer
1. 定义方法
Django REST framework中的Serializer使用类来定义须继承自rest_framework.serializers.Serializer。
例如我们已有了一个数据库模型类BookInfo
class BookInfo(models.Model):btitle models.CharField(max_length20, verbose_name名称)bpub_date models.DateField(verbose_name发布日期, nullTrue)bread models.IntegerField(default0, verbose_name阅读量)bcomment models.IntegerField(default0, verbose_name评论量)image models.ImageField(upload_tobooktest, verbose_name图片, nullTrue)我们想为这个模型类提供一个序列化器可以定义如下
class BookInfoSerializer(serializers.Serializer):图书数据序列化器id serializers.IntegerField(labelID, read_onlyTrue)btitle serializers.CharField(label名称, max_length20)bpub_date serializers.DateField(label发布日期, requiredFalse)bread serializers.IntegerField(label阅读量, requiredFalse)bcomment serializers.IntegerField(label评论量, requiredFalse)image serializers.ImageField(label图片, requiredFalse)**注意serializer不是只能为数据库模型类定义也可以为非数据库模型类的数据定义。**serializer是独立于数据库之外的存在。
2. 字段与选项
常用字段类型
字段字段构造方式**BooleanField**BooleanField()**NullBooleanField**NullBooleanField()**CharField**CharField(max_lengthNone, min_lengthNone, allow_blankFalse, trim_whitespaceTrue)**EmailField**EmailField(max_lengthNone, min_lengthNone, allow_blankFalse)**RegexField**RegexField(regex, max_lengthNone, min_lengthNone, allow_blankFalse)**SlugField**SlugField(max_length50, min*lengthNone, allow_blankFalse)正则字段验证正则模式 [a-zA-Z0-9*-]**URLField**URLField(max_length200, min_lengthNone, allow_blankFalse)**UUIDField**UUIDField(formathex_verbose)format:1) hex_verbose 如5ce0e9a5-5ffa-654b-cee0-1238041fb31a2 hex 如 5ce0e9a55ffa654bcee01238041fb31a3int - 如: 1234567890123123131341245123511451451144urn 如: urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a**IPAddressField**IPAddressField(protocolboth, unpack_ipv4False, **options)**IntegerField**IntegerField(max_valueNone, min_valueNone)**FloatField**FloatField(max_valueNone, min_valueNone)**DecimalField**DecimalField(max_digits, decimal_places, coerce_to_stringNone, max_valueNone, min_valueNone)max_digits: 最多位数decimal_palces: 小数点位置**DateTimeField**DateTimeField(formatapi_settings.DATETIME_FORMAT, input_formatsNone)**DateField**DateField(formatapi_settings.DATE_FORMAT, input_formatsNone)**TimeField**TimeField(formatapi_settings.TIME_FORMAT, input_formatsNone)**DurationField**DurationField()**ChoiceField**ChoiceField(choices)choices与Django的用法相同**MultipleChoiceField**MultipleChoiceField(choices)**FileField**FileField(max_lengthNone, allow_empty_fileFalse, use_urlUPLOADED_FILES_USE_URL)**ImageField**ImageField(max_lengthNone, allow_empty_fileFalse, use_urlUPLOADED_FILES_USE_URL)**ListField**ListField(child, min_lengthNone, max_lengthNone)**DictField**DictField(child)
选项参数
参数名称作用**max_length**最大长度**min_lenght**最小长度**allow_blank**是否允许为空**trim_whitespace**是否截断空白字符**max_value**最小值**min_value**最大值
通用参数
参数名称说明**read_only**表明该字段仅用于序列化输出默认False**write_only**表明该字段仅用于反序列化输入默认False**required**表明该字段在反序列化时必须输入默认True**default**反序列化时使用的默认值**allow_null**表明该字段是否允许传入None默认False**validators**该字段使用的验证器**error_messages**包含错误编号与错误信息的字典**label**用于HTML展示API页面时显示的字段名称**help_text**用于HTML展示API页面时显示的字段帮助提示信息
3. 创建Serializer对象
定义好Serializer类后就可以创建Serializer对象了。
Serializer的构造方法为
Serializer(instanceNone, dataempty, **kwarg)说明
1用于序列化时将模型类对象传入instance参数
2用于反序列化时将要被反序列化的数据传入data参数
3除了instance和data参数外在构造Serializer对象时还可通过context参数额外添加数据如
serializer AccountSerializer(account, context{request: request})通过context参数附加的数据可以通过Serializer对象的context属性。
序列化使用
我们在django shell中来学习序列化器的使用。
python manage.py shell1 基本使用
1 先查询出一个图书对象
from booktest.models import BookInfobook BookInfo.objects.get(id2)2 构造序列化器对象
from booktest.serializers import BookInfoSerializerserializer BookInfoSerializer(book)3序列化数据
通过data属性可以序列化后的数据
serializer.data# {id: 2, btitle: 天龙八部, bpub_date: 1986-07-24, bread: 36, bcomment: 40, image: None}
4如果要被序列化的是包含多条数据的查询集QuerySet可以通过添加manyTrue参数补充说明
book_qs BookInfo.objects.all()
serializer BookInfoSerializer(book_qs, manyTrue)
serializer.data# [OrderedDict([(id, 2), (btitle, 天龙八部), (bpub_date, 1986-07-24), (bread, 36), (bcomment, 40), (image, N]), OrderedDict([(id, 3), (btitle, 笑傲江湖), (bpub_date, 1995-12-24), (bread, 20), (bcomment, 80), (imagene)]), OrderedDict([(id, 4), (btitle, 雪山飞狐), (bpub_date, 1987-11-11), (bread, 58), (bcomment, 24), (ima None)]), OrderedDict([(id, 5), (btitle, 西游记), (bpub_date, 1988-01-01), (bread, 10), (bcomment, 10), (im, booktest/xiyouji.png)])]
2 关联对象嵌套序列化
如果需要序列化的数据中包含有其他关联对象则对关联对象数据的序列化需要指明。
例如在定义英雄数据的序列化器时外键hbook即所属的图书字段如何序列化
我们先定义HeroInfoSerialzier除外键字段外的其他部分
class HeroInfoSerializer(serializers.Serializer):英雄数据序列化器GENDER_CHOICES ((0, male),(1, female))id serializers.IntegerField(labelID, read_onlyTrue)hname serializers.CharField(label名字, max_length20)hgender serializers.ChoiceField(choicesGENDER_CHOICES, label性别, requiredFalse)hcomment serializers.CharField(label描述信息, max_length200, requiredFalse, allow_nullTrue)对于关联字段可以采用以下几种方式
1 PrimaryKeyRelatedField
此字段将被序列化为关联对象的主键。
hbook serializers.PrimaryKeyRelatedField(label图书, read_onlyTrue)
或
hbook serializers.PrimaryKeyRelatedField(label图书, querysetBookInfo.objects.all())指明字段时需要包含read_onlyTrue或者queryset参数
包含read_onlyTrue参数时该字段将不能用作反序列化使用包含queryset参数时将被用作反序列化时参数校验使用
使用效果
from booktest.serializers import HeroInfoSerializer
from booktest.models import HeroInfo
hero HeroInfo.objects.get(id6)
serializer HeroInfoSerializer(hero)
serializer.data# {id: 6, hname: 乔峰, hgender: 1, hcomment: 降龙十八掌, hbook: 2}
2使用关联对象的序列化器
hbook BookInfoSerializer()使用效果
{id: 6, hname: 乔峰, hgender: 1, hcomment: 降龙十八掌, hbook: OrderedDict([(id, 2), (btitle, 天龙八部)te, 1986-07-24), (bread, 36), (bcomment, 40), (image, None)])}3) StringRelatedField
此字段将被序列化为关联对象的字符串表示方式即__str__方法的返回值
hbook serializers.StringRelatedField(label图书)使用效果
{id: 6, hname: 乔峰, hgender: 1, hcomment: 降龙十八掌, hbook: 天龙八部}3 many参数
如果关联的对象数据不是只有一个而是包含多个数据如想序列化图书BookInfo数据每个BookInfo对象关联的英雄HeroInfo对象可能有多个此时关联字段类型的指明仍可使用上述几种方式只是在声明关联字段时多补充一个manyTrue参数即可。
此处仅拿PrimaryKeyRelatedField类型来举例其他相同。
在BookInfoSerializer中添加关联字段
class BookInfoSerializer(serializers.Serializer):图书数据序列化器id serializers.IntegerField(labelID, read_onlyTrue)btitle serializers.CharField(label名称, max_length20)bpub_date serializers.DateField(label发布日期, requiredFalse)bread serializers.IntegerField(label阅读量, requiredFalse)bcomment serializers.IntegerField(label评论量, requiredFalse)image serializers.ImageField(label图片, requiredFalse)heroinfo_set serializers.PrimaryKeyRelatedField(read_onlyTrue, manyTrue) # 新增使用效果
from booktest.serializers import BookInfoSerializer
from booktest.models import BookInfo
book BookInfo.objects.get(id2)
serializer BookInfoSerializer(book)
serializer.data# {id: 2, btitle: 天龙八部, bpub_date: 1986-07-24, bread: 36, bcomment: 40, image: None, heroinfo_set: [6,8, 9]}
未完待续 下一期下一章
全套笔记直接地址 请移步这里