Python教程之Django框架-视图集方式

    xiaoxiao2023-09-19  130

    Python教程之Django框架-视图集方式

    Django框架介绍RESTful架构详解 ① 项目搭建(终端中)② 项目配置(setting.py文件中)一、注册 DRF框架 和 子应用(INSTALLED_APPS中):二、注册 视图集(子应用模块的urls.py文件中): ③ 创建 数据表模型一、安装 pymysql扩展(终端):二、配置 pymysql扩展(在setting.py文件目录的__init__.py文件中):三、配置 mysql数据库(setting.py文件中):四、创建 数据库(终端):五、创建 数据表(子应用模块的models.py文件中):五、数据表模型 导入 数据库(终端):六、添加 记录(shell语法 - Manager管理器 提供):七、修改 记录(shell语法 - Manager管理器 提供):八、查询 记录(shell语法 - Manager管理器 提供):九、操作 查询记录对象(shell语法 - Manager管理器 提供): ④ 创建 序列化器(serializers.py文件中)⑤ 创建 DRF框架接口-视图集(views.py文件中)⑥ 使用 序列化器

    Django框架介绍

    python语言写的开源web开发的重量级框架,遵循MVT设计,不容易实现自定义。 特色是简便、快速的开发数据库驱动的网站,它强调代码复用,多个组件以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,使Django具有很强的可扩展性 MVT(Model-View-Template) M: 数据库交互模块# V: 控制器,控制所有模块# T: web封装模块#

    RESTful架构详解

    一、设计理论:

    具象的:每一个URL 返回 一种资源表现:每种资源 都被指定了 具体数据格式 (请求头中 Accept和Content-Type)状态转换:前端和服务器交互过程中 请求状态和数据的变化 HTTP协议请求状态和请求规范: 常用: (GET请求:获取资源)(POST请求:新建资源) 不常用: (PUT请求:更新资源 前端提供改变的实参)(PATCH请求:更新资源 前端提供改变的形参)(DELETE请求:删除资源)(HEAD请求:获取资源(原始数据))(OPTIONS请求:获取前端可以操作的资源信息)

    二、设计规范:

    域名:尽量将API接口部署在专用域名之下 例:https://api.example.com版本:在URL中 区分API版本 例:http://域名/app/1.0/路由路径:资源作为网址,只能有名词(复数),不能有动词,而且所用名词与数据库的表名对应 例: GET请求: /数据表名 :获取 所有资源POST请求: /数据表名 :新建 资源GET请求: /数据表名/4 :获取 4号资源PUT请求: /数据表名/4 :更新 4号资源DELETE请求: /主键表名/ID/外键表名/ID:删除 指定主键记录关联外键记录 过滤信息:API提供路由参数 过滤返回结果 例:?page=2&per_page=100:指定第几页,以及每页的记录数。状态码: 例:  200 OK - [GET]:服务器成功返回用户请求的数据  201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。  202 Accepted - []:表示一个请求已经进入后台排队(异步任务)  204 NO CONTENT - [DELETE]:用户删除数据成功。  400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作  401 Unauthorized - []:表示用户没有权限(令牌、用户名、密码错误)。  403 Forbidden - [] 表示用户得到授权(与401错误相对),但是访问是被禁止的。  404 NOT FOUND - []:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。  406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。  410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。  422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。  500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。错误处理:如果状态码是4xx,服务器就应该向用户返回出错信息 例:{error: “错误提示信息”}返回结果的数据规范:针对不同请求状态和路由地址,服务器向用户返回内容应该遵循一定规范 例:  GET /collection:返回资源对象的列表(数组)  GET /collection/resource:返回单个资源对象  POST /collection:返回新生成的资源对象  PUT /collection/resource:返回完整的资源对象  PATCH /collection/resource:返回完整的资源对象  DELETE /collection/resource:返回一个空文档返回结果的超媒体链接:返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么 例:{“current_user_url”: “https://api.github.com/user”, …}其他:服务器返回的数据格式,应该尽量使用JSON,避免使用XML

    三、核心流程: 1. 序列化(输出):数据库对象 → python数据(比如JSON) 2. 操作数据库 3. 反序列化(输入):请求数据→验证→ python数据(比如JSON)

    ① 项目搭建(终端中)

    一、安装:

    安装Django框架:pip3 install django==1.11.11安装DRF框架:pip3 install djangorestframework

    二、创建 Django项目:

    创建工程:django-admin startproject 工程名 (在当前目录下 生成 工程配置文件)启动工程服务器(终端):python3 manage.py runserver 「ip:端口」 (默认IP是127.0.0.1 默认端口为8000) (默认Debug模式启动 项目文件变动 服务器自动重启)重启工程服务器:sudo service mysql restartxx创建子应用: 方式一:python3 manage.py startapp 子应用模块名 (会检索 已注册的子应用模块 检索错误 会报ImportError导包异常) 方式二:django-admin startapp 子应用模块名 (站点创建)

    三、shell命令模式: python3 manage.py shell

    ② 项目配置(setting.py文件中)

    一、注册 DRF框架 和 子应用(INSTALLED_APPS中):

    工程 注册 DRF框架:'rest_framework',工程 注册 子应用:'子应用模块名.apps.子应用模块名Config',

    二、注册 视图集(子应用模块的urls.py文件中):

    子应用 注册 视图集(DRF框架提供-路由器注册): from rest_framework.routers import DefaultRouter/SimpleRouter #导入 路由器# router = DefaultRouter()/SimpleRouter() # 创建 新路由器# router.register(r'^##请求地址前缀##/$', views.视图名, base_name='路由名前缀') # 新路由器中 注册 类视图/视图集# urlpatterns += router.urls # 新路由信息 追加到 django路由列表#

    ③ 创建 数据表模型

    一、安装 pymysql扩展(终端):

    `pip3 install pymysql`

    二、配置 pymysql扩展(在setting.py文件目录的__init__.py文件中):

    from pymysql import install_as_MySQLdb install_as_MySQLdb()

    三、配置 mysql数据库(setting.py文件中):

    DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', # 数据库主机 'PORT': 3306, # 数据库端口 'USER': '数据库用户名', 'PASSWORD': '数据库用户密码', 'NAME': '数据库名字', 'OPTIONS':{##mysql数据库配置##} } }

    四、创建 数据库(终端):

    `create database 数据库名 default charset=utf8;`

    五、创建 数据表(子应用模块的models.py文件中):

    定义 数据表(models.py文件中):class 数据表类名(models.Model): 字段名 = models.##字段类型##(##字段约束##) #---------------------------------------------常用字段-------------------------------------------------# 自动生成主键名_id = AutoFields(primary_key=True,) 自定义主键名_id = models.AutoField(primary_key=True,) 字符串字段名 = models.CharField(max_length=32, verbose_name='站点名') 日期字段名= models.DateField(verbose_name='站点名') #外键关联: 在数据库中 外键字段名会自动加上 '_id'# 外键字段名_主键表名 = models.ForeignKey(主表类名,on_delete=models.CASCADE, verbose_name='') #外键自关联: 通过self关联自己# 外键字段名_外键表名 = models.ForeignKey('self',...) #---------------------------------------------定义表名-------------------------------------------------# class Meta: ##Meta配置## #--------------------------------------------查询记录对象时 返回结果-----------------------------------# def __str__(self): return self.字段名 #原本返回的记录对象 变成 指定字段的记录值返回#

    五、数据表模型 导入 数据库(终端):

    生成迁移文件:python3 manage.py makemigrations 「子应用名」创建/更新(迁移) 数据表: python3 manage.py migrate 「子应用名」

    六、添加 记录(shell语法 - Manager管理器 提供):

    ```python 记录对象名 = 数据表类名.objects.create(字段名=值, 外键字段名=主键表记录对象, # 外键记录 方式一# 外键字段名_id=整数, # 外键记录 方式二# ...) ```

    七、修改 记录(shell语法 - Manager管理器 提供):

    `数据表类名.objects.filter(字段名=值).update(字段名=新值)`

    八、查询 记录(shell语法 - Manager管理器 提供):

    `记录对象名 = 数据表类名.objects.##输出类型##「.##优化查询##」` 输出类型: 返回 单个记录对象(格式: <数据表类名: 记录对象>): 指定记录对象:get(字段名=值,...)指定字段 最新记录对象:latest('字段名') 返回 返回 查询集(格式: <QuerySet [<数据表类名: 记录对象>,…]>): 所有记录:all()原始查询:raw('##select语句##')过滤查询(多个条件约束用逗号隔开 但字段条件不能重复): 过滤:filter(##条件约束##)反过滤:exclude(##条件约束##) ##条件约束 语法## 字段名=值 字段名__##条件运算符##=值 字段名__##条件运算符##=(值1,值2,...) 字段名__##条件运算符##=F('字段名') # F对象: 比较字段# Q(条件约束1) | ~Q(条件约束2) & ... # Q对象: &表示与、|表示或、~Q表示非# 外键表名__外键表任意字段名__##条件运算符##=值 #主键表 查 外键表# 主键表名__主键表任意字段名__##条件运算符##=值 #外键表 查 主键表# #---------------------条件运算符---------------------# 相等:exact 包含-单个(字符串):contains 包含-多个(列表)in 开头/结尾:startswith/endswith 为null:isnull 比较-大于:gt 比较-大于等于:gte 比较-小于:lt 比较-小于等于:lte 日期(只能查询 DateField字段类型): 日期-年:year 日期-月:month 日期-日:day 日期-星期几:week_day 日期-时:hour 日期-分:minute 日期-秒:second 优化查询: 输出 指定字段:only('字段名1',「字段名2,...」)总记录条数:coumt()聚合函数:aggregate(约束函数名('字段名')) 平均数:Avg 最大数:Max 最小数:Min 求和:Sum 排序(默认为正序 '-'号为降序):order_by('字段名1',「'-字段名2',...」)优化 外键查询(重点) 一查一:select_related(##优化参数##」) 一查多:prefetch_related(##优化参数##」) 优化参数(原生):外键字段名 优化参数(Prefetch方法):Prefetch('外键字段名',##外键表查询集(过滤作用)##,'序列化器的外键字段名') 注意: 一查一时(外键表查主键表) 使用 '外键字段名' 一查多时(主键表查外键表) 使用 '外键表名_set'

    九、操作 查询记录对象(shell语法 - Manager管理器 提供):

    获取 单个记录对象 和 字段值: 取 单个记录对象:查询集名[索引位]取 单个记录对象的字段值:单个记录对象名.字段名 获取 外键记录对象 外键表 查 主键表:查询集名[索引位] 一查一:外键表记录对象名.OneToOneField字段名一查一:外键表记录对象名.ForeignKey字段名一查多:外键表记录对象名.ManyToManyField字段名.##输出类型## 主键表 查 外键表 一查一(通过OneToOneField字段):主键表记录对象名.外键表类名(小写)一查多 (原生):主键表记录对象名.外键表类名(小写)_set.##输出类型##

    ④ 创建 序列化器(serializers.py文件中)

    from rest_framework import serializers from 子应用模块名.models import 数据表类名 class 序列化器名(serializers.ModelSerializer): 字段名 = serializers.##序列化字段类型##(##字段参数##) #补充 要序列化的字段# #-------------------------------------------------定义 关联查询--------------------------------------------------# #方式一: 外键字段方式 输出 id字段值# 外键字段名_主键表名 = serializers.PrimaryKeyRelatedField(read_only=True) #一查一: 在外键表的序列化器中# 外键字段名_外键表名_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True) #一查多: 在主键表的序列化器中# #方式二: 通用方式 输出 所有字段值# 外键字段名_主键表名 = 主键表序列化器名() #一查一: 在外键表的序列化器中# 外键字段名_外键表名_set = 主键表序列化器名(many=True) #一查多: 在主键表的序列化器中# #-------------------------------------------------通用序列化器---------------------------------------------------# class Meta: model = 数据表类名 #引用 数据表模型中的字段# ##通用序列化器语法##

    ⑤ 创建 DRF框架接口-视图集(views.py文件中)

    from 子应用模块名.models import 数据表类名 from .serializers import 序列化器名 ##导入 DRF框架的 类视图模板## class 类视图名_数据表类名继承的DRF类视图名(##继承 DRF框架的 类视图模型##): def 方法名(self,request,「路径形参名,...): ##视图语法## #--------------------------------常用-视图集---------------------------------# from rest_framework.viewsets import ModelViewSet 「from rest_framework.decorators import action」 class 视图集名(ModelViewSet): 通用记录对象名_queryset = 数据表类.objects.all() 通用序列化器_serializer_class = 序列化器名 #----附加 自定义action动作(detail表示 是否获取路径参数)----# @action(methods=['##请求方式##], detail=##布尔值##) def 自定义action动作名(self, request,「pk」): #----------------获取 记录对象(GenericAPIView类 提供)----------------# 查询集对象名 = self.get_queryset() #无参路由时# 查询记录对象名 = self.get_object() #有参路由时# #----------------获取 序列化器(GenericAPIView类 提供)----------------# 序列化器类名 = self.get_serializer_class() #获取 序列化器类# 序列化器对象名= self.get_serializer(##查询记录对象##) #获取 序列化器对象# ##视图语法##

    ⑥ 使用 序列化器

    使用 序列化(输出): 获取 从数据库中 序列化后的数据(rander渲染前):序列化器对象名.data 使用 反序列化(输入-省略验证方法) 获取 从前端中 验证通过的 反序列化后的数据:序列化器对象名.data获取 状态码:序列化器名.status_code新建/修改 记录(返回 这个记录对象):序列化器对象名.save(##参数##) 新建记录时(调用 create方法):data=##json字典##修改记录时(调用 update方法):记录对象名.data=##json字典##允许传入 额外参数:额外形参名=实参允许保存 部分字段:partial=True
    最新回复(0)