重点内容回顾-DRF

重点内容回顾-DRF

文章共: 4391字 4图
预计阅读时间: 15分钟

每日分享

Overthinking ruins you. Ruins the situation, twists it around, makes you worry and just makes everything much worse than it actually is.

过度的思考会毁了你。使你现在的处境糟糕,让你曲解其中的意思,让你担忧,让每一件事都变的更加的糟糕。

小闫语录:

事情不要看太透,做人不要太精明。不知道你有没有听说过一个词『大智若愚』,它是一种大智慧,有德有智,看透万物,但是不去计较那么多。将格局放大,将眼光放远,你会发现不一样的世界。也许你会为了一件小事耿耿于怀,也许你会因为一件琐事久久不能释怀,甚至影响了你正常的生活。并不是说你错,在这件事上你占理,这件事你想的没错,只是它不值得你去花费如此多的精力罢了。将所有的精力放在你主要的事情上,对于一些琐事、一些惹恼的小人,一些阻碍你前进的事物,不妨看淡一点,暂时的妥协并不是向他们低头,而是跟本没把他们放在心上。事情不要想的的太透,太过的执拗会让你走向错误的方向,点到即止,一句话也许只是表面意思,并没有那么多深层意思。做人不要太精明,看透不说透,不要将自己过的那么累,也不要给别人难堪。

1.on_delete

on_delete是定义模型类中外键的一个选项。

on_delete选项指明的是主表删除数据的时候,对于外键引用的表数据如何处理。

在django.db.models中包含了可选的常量,常用的有三种:

a.CASCADE级联,删除主表数据的时候,连同删除外键表中的数据。这个就有点狠了,按需求慎用。

b.PROTECT保护,通过抛出一个异常ProtectedError异常,来阻止删除主表中被外键引用的数据。

c.SET_NULL设置为NULL,代表的是主表删除数据的时候,将外键关联的表数据设置为NULL。仅仅在该字段null=True,允许为null时可用。

2.related_name

related_name是在定义模型类时,外键的一个选项。它的功能下面慢慢给大家分析一下。

之前我们在数据库查询操作中,由一查多的时候,是下面的操作:

# 1.查询id为200001的地区
area = Area.objects.get(id=200001)
# 2.查询area的下级地区
# 由一查多:一对象.多类名小写__set.all()
sub_areas = area.area_set.all()

一旦设置了related_name='subs'的时候,我们查询area的下级地区的时候,就可以改为下面的操作:

sub_areas = area.subs.all()

相当于是将多类名小写_set改为了related_name设置的subs。是不是很方便呢?

ForeignKey('self')代表的是自关联

3.一些常用的命令

a. 创建Django工程:

django-admin startproject 工程名称

b. 创建子应用:

python manage.py startapp 子应用名称

c. 使用shell:

python manage.py shell

d. 打开celery执行者:(一定要在celery的目录上一级打开打开终端执行命令)

celery -A celery目录.main worker -l 日志级别
celery -A celery_task.main worker -l info

e. 我们设置了前端开发服务器,所以每次使用的时候一定要记得打开:(在静态文件目录下执行下面的命令)

live-server

f. 迁移

生成迁移文件:

python manage.py makemigrations

同步到数据库中:

python manage.py migrate

g. MySQL数据库中修改表中数据:

update 表名 set 字段名=要改的值 [where 查询指定数据的条件]
update tb_users set email_active=0 where id=2

h. shell脚本添加地区数据:(是直接远程连接导入数据)

mysql -u<用户名> -p<密码> -h<数据库服务器> <数据库名> < sql文件;
mysql -umeiduo -pmeiduo -h172.16.179.139 meiduo_mall < areas.sql;

要想上面的命令将来可以被多次执行,可以将上面的命令写入一个.sh文件中,在文件的首行必须指定一行命令:

#! /bin/bash

也许每个人电脑中bash的位置不同,根据自己电脑写即可,mac和Ubuntu中是不同的。

最后还要想执行该shell文件,必须修改文件的可执行权限:(这条命令作为帮助大家回忆Linux命令)

chmod a+x import_areas_data_to_db.sh

上面的chmod不需要解释,a代表的是all(即全部三者:u(user该文件的所有者)、g(group该文件所有者所在的用户组)、o(other表示其他用户)),x代表的是执行权限。上面的命令的意思就是『此文件给所有的用户添加执行权限』

+代表的是增加权限、-代表的是撤销权限、=代表的是设定权限

r代表可读权限,就是可以通过ls命令查看这个目录的内容。

w代表的是写入权限,就是可以通过touch等命令在该目录下创建新文件。

x代表的是执行权限,就是可以通过cd命令进入这个目录等。

4.关联对象的嵌套序列化

4.1PrimaryKeyRelatedField

将关联对象序列化为关联对象的主键。

subs = PrimaryKeyRelatedField(label='下级地区',read_only=True)
或者:
subs = PrimaryKeyRelatedField(label='下级地区',queryset=Area.objects.all())

包含read_only=True参数的时候,该字段仅仅用在序列化。

包含queryset参数的时候,将被用在反序列化时参数校验。

4.2使用关联对象的序列化器类

采用指定的序列化器将关联对象进行序列化

subs = AreaSerializer(label='下级地区',many=True)

4.3StringRelatedField

将关联对象序列化为关联对象的字符串表示方式,(即关联对象模型类_str_方法的返回值)

subs = serializers.StringRelatedField(label='下级地区')

说明

我们在昨天的文章中查询指定地区的时候,接口设计中响应数据如下:

{
    "id":"地区id",
    "name":"地区名称",
    "subs":[
        {
            "id":"下级地区",
            "name":"下级地区名称"
        }
    ]
}

根据上面可知,我们只需要将数据序列化为id和name,那么我们使用指定的序列化器类序列化即可。

5.DRF框架

5.1web开发两种模式

前后端不分离:前端看到的效果是由后端进行控制,由后端进行模板渲染,给客户端返回渲染之后完整的页面内容。

前后端分离:后端只返回前端所需的数据,至于数据怎么显示,由前端自己控制。

5.2Restful API接口设计风格

关键点

a.url地址尽量使用名词,不要使用动词;

b.请求url地址采用不同的请求方式执行不同的操作;(POST新增/GET获取/PUT修改/DELETE删除)

c.过滤参数可以放在查询字符串中;

d.响应数据返回&响应状态码;(200获取或修改成功/201新增成功/204删除成功/404资源不存在/400客户端请求有误/500服务器错误)

e.响应数据格式JSON。

5.3序列化&反序列化

下面从我们最近推文的项目来简单的理解两个概念。

序列化:将模型对象转换为字典或者json数据的过程。

反序列化:将前端传递的数据保存到模型对象中的过程。

5.4序列化器Serializer

5.4.1功能

进行数据的序列化和反序列化。

5.4.2序列化器定义

继承自serializers.Serializer重点掌握),里面的字段需要自己定义。

class 序列化器类名(serializers.Serializer):
    # 字段名 = serializer.字段类型(选项参数)

如果我们想要使用序列化器对应的是Django的模型类,那么可以继承自serializers.ModelSerializer,它会依据模型类的字段自动生成序列化器类的字段,而且已经实现了create和update的代码。

在使用ModelSerializer的时候,可以使用model来指定模型类,使用fields来指定具体生成的字段,使用exclude可以明确排除掉哪些字段,使用read_only_fields来指明只读字段,即仅用于序列化输出的字段。我们还可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数。

序列化对象的创建

序列化器类(instance=<实例对象>, data=<数据>, **kwargs)

如果是想将对象序列化,那么将其赋值给instance;

如果是数据校验,那么将数据赋值给data。

5.4.3序列化功能

将实例对象转换为字典数据:

a.序列化单个对象。

b.序列化多个对象。(其实就是在序列化单个对象的基础上多加了一个参数many=True)

c.关联对象的嵌套序列化。(详情见本文标题4)

json.dumps()是将字典转换成json字符串

json.loads()是将json字符串转换成字典数据

5.4.4反序列化功能

1.数据校验

我们可以调用is_valid()来进行数据的校验,我们还可以补充额外的验证

a.先写一个函数(如about_django)封装补充验证的功能,然后在字段中添加validators参数,如下:

btitle = serializers.CharField(...,validators=[about_django])

b.在序列化器中定义一个方法validate_<field_name>,来对<field_name>字段进行验证。

def validate_btitle(self, value):
    ...
    return value

c.在序列化器中定义validate方法进行补充验证(结合多个字段内容验证)

def validate(self, attrs):
    # 此处的attrs是一个字典类型的数据,创建序列化器对象的时候,传入的data数据
    ...
    return attrs

2.数据保存(新增&更新)

在创建序列化对象的时候如果只是传入了data参数,那么就会调用create方法进行数据保存;如果还传入了instance对象,那么就会调用update方法进行数据的更新操作。

注意:校验通过之后,要调用serializer.save()进行数据的保存。

5.5视图类

5.5.1功能

1.使用序列化器(数据校验,数据保存,数据的序列化)。

2.进行数据库的相关查询。

5.5.2视图基类

5.5.2.1APIView

是View类的子类,在View类的基础上添加了一些额外的功能。

功能

1.视图中request对象不再是Django中原始的HttpRequest类的对象,而是DRF框架封装的Request类的对象。

request.data保存的是解析之后的请求体的数据,并且已经解析成了字典或类字典,相当于包含Django原始request对象中的request.body/request.POST/request.FILES

request.query_params保存解析之后的查询字符串的数据,并且已经解析成了字典或类字典,相当Django原始request对象中的request.GET

2.响应时可以统一返回Response类的对象。

Response类的对象:传入原始的响应数据,会自动根据客户的请求头中Accept将响应数据转换为对应的格式进行返回,默认是json,仅支持json和html

3.异常处理:如果视图中抛出了未处理异常,DRF框架会自动对异常进行处理,并且会把处理之后的错误信息返回给客户端。

4.高级功能:认证、权限、限流

5.5.2.2GenericAPIView

是APIView的子类,在APIView的基础上添加操作序列化器和数据库查询的方法。

操作序列化器:

属性

serializer_class(指定视图所使用的序列化器类)

方法

get_serializer_class返回视图所使用的序列化器类

get_serializer创建视图所使用的序列化器类对象。

数据库查询

属性

queryset(指定视图所使用的查询集)

方法

get_queryset返回视图所使用的查询集

get_object从视图所使用的查询集中查询指定的对象,默认根据pk进行查询。

其他功能

过滤、分类

通常GenericAPIView配合Mixin扩展类进行使用

5.5.2.3Mixin扩展类

DRF框架提供了5个扩展类,封装了通用增删改查的流程。

ListModelMixin

提供了一个list方法,封装了获取一组数据的通用流程。

CreateModelMixin

提供了一个create方法,封装了新增一条数据的通用流程。

RetrieveModelMixin

提供了一个retrieve方法,封装了获取指定数据的通用流程。

UpdateModelMixin

提供了一个update方法,封装了更新指定数据的通用流程。

DestroyModelMixin

提供了一个destroy方法,封装了删除指定数据的通用流程。

为了方便我们开发RestAPI,DRF框架除了提供APIView和GenericAPIView视图类之外,还提供了一些子类视图类,这些子类视图类同时继承了GenericAPIView和对应的Mixin扩展类,并且提供了对应的请求方法。

5.6视图集

5.6.1概念

将操作同一组资源的处理方法(API接口)放在同一个类中

5.6.2注意点

1.视图集中的处理方法不再以请求方法命名,而是以对应的操作(action)名称命名:list/create/update/retrieve/destroy

2.在进行url配置的时候,要指明请求地址的请求方式和视图集中处理函数之间的对应关系。

url(r'^books/$',views.BookInfoViewSet.as_view({
    'get':'list',
    'post':'create'
}))

5.6.3视图集父类

ViewSet

最基础的父类,我们一般不使用

GenericViewSet

继承自ViewSetMixin和GenericAPIView,可以配合Mixin扩展类提供对应的处理方法。

ModelViewSet

继承自GenericViewSet和5个对应Mixin扩展类。如果视图集中一次性想要提供5个接口的时候,我们可以继承此父类。

ReadonlyModelViewSet

继承自GenericViewSet和ListModelMixin, RetrieveModelMixin。如果视图集中只想提供list和retrieve接口的时候,可以继承此父类。

5.6.4视图集中添加额外的处理方法

1.直接在视图集定义额外的处理方法即可

2.在进行url配置的时候也要指定请求地址请求方式和处理函数之间的对应的关系。

5.6.5视图集对象的action属性

视图集对象的action属性是一个字符串,我们可以根据action获取所要执行的是哪一种操作。

使用场景

根据不同的操作返回不同的序列化器类和不同的查询集,重写get_serializer_classget_queryset方法。

def get_serializer_class(self):
    if self.action == 'list':
        # 返回list操作对应的序列化器类
    elif self.action == 'latest':
        # 返回latest操作对应的序列化器类
    else:
        # 返回其他操作对应的序列化器类
        
def get_queryset(self):
    if self.action == 'list':
        # 返回list操作使用的查询集
    elif self.action == 'latest':
        # 返回latest操作使用的查询集
    else:
        # 返回其他操作所使用的查询集

5.6.6路由Router

作用

配合视图集进行使用,动态生成视图集中处理函数的url配置项。

使用

1.创建Router类的对象

from restframe_work.routers import SimpleRouter,DefaultRouter
router = SimpleRouter()

2.注册视图集

router.register(prefix,viewset,base_name)

prefix 该视图集的路由前缀

viewset 视图集

base_name 路由名称的前缀

3.将生成的url配置项列表添加urlpatterns中

urlpatterns += router.urls
视图集额外处理方法url配置项的生成

需要给对应的方法添加action装饰器。

@action(methods=['get'], detail=False)
def latest(self, request):
    ...
    return Response(...)

methods 声明该action对应的请求方式,列表传递

detail 声明该action的路径是否与单一资源对应。举个例子:True表示的是xxx/<pk>/action方法名,而False表示的是xxx/action方法名

6.高级功能

6.1分页

我们可以在配置文件中设置全局的分页方式

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  '<全局分页类>',
    'PAGE_SIZE': <页容量>  
}

6.1.1分页类

PageNumberPagination

前端访问网址的形式需要在后面跟

?page=<页码>

LimitOffsetPagination

前端访问网址的形式需要在后面跟

?offset=<偏移量>&limit=<数据条数>

6.1.2自定义分页类

class StandardResultPagination(PageNumberPagination):
    # 指定页容量
    page_size = 3
    # 指定获取分页数据时,传递的也容量参数名称
    page_size_query_param = 'page_size'
    # 指定最大页容量
    max_page_size = 5

前端访问网址的形式需要在后面跟

?page=<页码>&page_size=<页容量>

视图关闭分页pagination_class = None

6.2异常处理

可以设置DRF框架的默认异常处理,也可以自定义异常处理函数。

def exception_handler(exc, context):
    # 先调用DRF框架的默认异常处理函数
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context['view']
        # 补充数据库的异常处理
        if isinstance(exc, DatabaseError):
            print('[%s]: %s' % (view, type(exc)))
            response = Response({'detail': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

然后需要在配置文件中声明自定义的异常处理。

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'booktest.utils.exceptions.exception_handler'
}

6.3其他

认证:可以进行DRF框架默认全局认证方案设置,也可以对其进行修改,还可以指定某个视图的认证方案。

权限:区分的是认证与未认证的用户。可以进行DRF框架默认全局权限设置,也可对其进行修改,还可以指定某个视图的权限控制设置,甚至可以自定义权限控制类。权限和认证通常是一起使用的。

限流:注意,是对用户访问API接口频次进行限制。我们既可以针对匿名用户和认证用户进行统一限流设置,也可以分开进行限流设置。

过滤:需要先安装django-filter并进行注册设置,再在视图中通过filter_fields设置过滤字段。

排序:设置filter_backends并通过ordering_fields设置排序字段。

自动生成接口文档:生成的接口文档并不全面,强烈建议,自己写接口文档。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,311评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,339评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,671评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,252评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,253评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,031评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,340评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,973评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,466评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,937评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,039评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,701评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,254评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,259评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,497评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,786评论 2 345

推荐阅读更多精彩内容

  • Django&DRF重点内容大盘点 本文只是将学习过程中需要深刻记忆,在工作中常用的一些命令或者知识点进行一个罗列...
    小闫同学啊阅读 4,243评论 0 10
  • 1. 视图 Django REST framwork 提供的视图的主要作用: 控制序列化器的执行(检验、保存、转换...
    childhood_1013阅读 81评论 0 0
  • 1. Web应用模式 在开发Web应用中,有两种应用模式: 前后端不分离 前后端分离 2. api接口 为了在团队...
    childhood_1013阅读 164评论 0 0
  • 安装Nginx:yum install -y nginxsystemctl start nginxsystemct...
    碧潭飘雪ikaros阅读 694评论 0 1
  • 1. 版本 了解* 可以放在url,这种是比较推荐的。它需要配套的路由,一般所有的CBV都要使用,所以放在全局配...
    上帝大人阅读 159评论 0 1