写点什么

开源一夏 | Python Web 开发(八):后端开发中的增查改删处理

作者:是Dream呀
  • 2022 年 8 月 02 日
  • 本文字数:4800 字

    阅读完需:约 16 分钟

开源一夏 | Python Web开发(八):后端开发中的增查改删处理

如果采用前后端分离的架构开发, 后端几乎不负责任何展现界面的工作,只负责对数据进行管理 。数据的管理,主要就是:响应前端的请求, 对数据资源的 增加、修改、删除、列出 。

一、创建 mgr 应用目录

接口文档明确说明了,这是针对 管理员用户 的 请求。


前面我们已经为 销售员用户 专门创建了一个应用 sales 来处理相关的 请求。


所以,我们可以 再为 管理员用户 专门创建一个应用 mgr 来处理相关的 请求进入根目录,执行:


python manage.py startapp mgr 
复制代码



此时我们会看见,目录下已将创建了一个 mgr 的文件夹:


二、添加处理请求模块 和 url 路由

前面,我们都是在 views.py 里面定义函数,处理 http 请求的。但是可以想象, 以后,这个 mgr 应用要处理很多类型的 http 请求。都用这个views.py 就会让这个文件非常的庞大, 不好维护。所以,我们可以用不同的 py 文件处理不同类型的 http 请求。比如,这里我们可以新增一个文件 customer.py, 专门处理 客户端对 customer 数据的操作。将来如果客户端有对其他类型数据的操作, 比如 order 数据, 我们就可以添加 orders.py 来处理。从接口文档,我们可以发现对资源的增删改查 操作, 都是同一个 URL,都是 /api/mgr/medicine 。而且我们发现,不同的操作请求,使用不同的 HTTP 请求方法 ,比如 添加是 POST, 查询是 GET, 修改是 PUT, 删除是 DELETE。且请求的参数中都有 action 参数表明这次请求的操作具体是什么。注意: Django 的 url路由功能 不支持 根据 HTTP 请求的方法 和请求体里面的参数 进行路由。就是不能像下面这样,来根据请求 是 post 还是 get 来 路由:


path('customers/', 'app.views.list_customer', method='get'),path('customers/', 'app.views.add_customer',  method='post'),
复制代码


那么大家想想该怎么办?

2.1 定义函数

一种方式是:自己编写一个函数, 来 根据 http 请求的类型 和请求体里面的参数 分发(或者说路由)给 不同的函数进行处理。

1.新建 customer 文件,定义 dispatcher 函数

我们可以 在 customer.py 中定义如下 dispatcher 函数:


def dispatcher(request):    # 将请求参数统一放入request 的 params 属性中,方便后续处理
# GET请求 参数在url中,同过request 对象的 GET属性获取 if request.method == 'GET': request.params = request.GET
# POST/PUT/DELETE 请求 参数 从 request 对象的 body 属性中获取 elif request.method in ['POST','PUT','DELETE']: # 根据接口,POST/PUT/DELETE 请求的消息体都是 json格式 request.params = json.loads(request.body)

# 根据不同的action分派给不同的函数进行处理 action = request.params['action'] if action == 'list_customer': return listcustomers(request) elif action == 'add_customer': return addcustomer(request) elif action == 'modify_customer': return modifycustomer(request) elif action == 'del_customer': return deletecustomer(request)
else: return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'})
复制代码


首先创建一个 custome.py 文件:



该函数 把 请求消息中的参数统一放入到 request 请求对象的 params 属性中。params 属性 被 做成一个 dict 类型 , 方便后面的处理函数来获取消息中的参数。然后 dispatch 函数再根据 请求的 类型 和 action 参数的值 决定由那个函数具体处理该请求消息。比如 action 参数‘add_customer’ 的 请求 就由 addcustomer 函数 进行处理。当然在文件的开头,我们需要 先导入 JsonResponsejson 的定义,像下面这样:


from django.http import JsonResponseimport json
复制代码



接下来,根据 API 接口 ,我们发现 凡是 API 请求 url 为 /api/mgr/customers 的,都属于 客户 相关的 API, 都应该交由 我们上面定义的 dispatch 函数进行分派处理。那么我们需要在 Django 的 url 路由文件中加入对应的路由。

2.总路由文件 bysms/urls.py 中定义

我们应该在 总路由文件 bysms/urls.py 中定义了如下部分:


    # 凡是 url 以 api/mgr  开头的,    # 都根据 mgr.urls 里面的 子路由表进行路由    path('api/mgr/', include('mgr.urls')),
复制代码

3.mgr 下添加 urls.py 路由文件

在 mgr 目录下面添加 urls.py 路由文件, 并 加入如下声明即可, 如下所示:


from django.urls import path
from mgr import customer
urlpatterns = [
path('customers', customer.dispatcher),]
复制代码


这样,就表示 凡是 API 请求 url 为 /api/mgr/customers 的,都交由 我们上面定义的dispatch函数进行分派处理。

三、列出客户

通常数据资源的 增查改删 里面的 查 就是 查看,对应的就是列出数据资源。


根据接口文档,列出客户数据接口,后端返回的数据格式如下:


{    "ret": 0,    "retlist": [        {            "address": "江苏省常州武进市白云街44号",            "id": 1,            "name": "武进市 袁腾飞",            "phonenumber": "13886666666"        },                {            "address": "北京海淀区",            "id": 4,            "name": "北京海淀区代理 蔡国庆",            "phonenumber": "13990123456"        }    ]              }
复制代码


这里我们无需 将数据库中获取的数据 转化为 供浏览器展示的 HTML。在前后端分离的开发架构中,如何展示数据,那是前端的事情。我们后端只需要根据接口文档, 返回原始数据就行。我们可以使用如下的函数来返回数据库的所有的 客户数据信息:


def listcustomers(request):    # 返回一个 QuerySet 对象 ,包含所有的表记录    qs = Customer.objects.values()
# 将 QuerySet 对象 转化为 list 类型 # 否则不能 被 转化为 JSON 字符串 retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist})
复制代码


当然在文件的开头,我们需要 先导入 Customer 定义,像下面这样:


# 导入 Customer from common.models import Customer
复制代码


可以发现,无需转化数据为 HTML, 后端的代码任务也大大减轻。

四、添加客户

通常数据资源的 增查改删 里面的 增 就是 添加,对应的就是添加数据资源。根据接口文档,添加客户数据接口,前端提供的客户数据格式如下:


{    "action":"add_customer",    "data":{        "name":"武汉市桥西医院",        "phonenumber":"13345679934",        "address":"武汉市桥西医院北路"    }}
复制代码


我们可以使用如下的函数来处理:


def addcustomer(request):
info = request.params['data']
# 从请求消息中 获取要添加客户的信息 # 并且插入到数据库中 # 返回值 就是对应插入记录的对象 record = Customer.objects.create(name=info['name'] , phonenumber=info['phonenumber'] , address=info['address'])

return JsonResponse({'ret': 0, 'id':record.id})
复制代码


Customer.objects.create 方法就可以添加一条Customer表里面的记录。

五、临时取消 CSRF 校验

根据接口文档,添加客户 请求是个 Post 请求


POST /网站名/api/mgr/signin  HTTP/1.1Content-Type:   application/x-www-form-urlencoded
复制代码


注意,缺省创建的项目, Django 会启用一个 CSRF (跨站请求伪造) 安全防护机制。在这种情况下, 所有的 Post、PUT 类型的 请求都必须在 HTTP 请求头中携带用于校验的数据。为了简单起见,我们先临时取消掉 CSRF的 校验机制,等以后有需要再打开。要临时取消掉 CSRF 的 校验机制,非常简单,只需要在 项目的配置文件 bysms/settings.pyMIDDLEWARE 配置项 里 注释掉 ‘django.middleware.csrf.CsrfViewMiddleware’ 即可。


六、修改客户信息

数据资源的 增查改删 里面的 改 就是 改动,对应的就是修改数据资源。根据接口文档,修改客户数据接口,前端提供的数据格式如下:


{    "action":"modify_customer",    "id": 6,    "newdata":{        "name":"武汉市桥北医院",        "phonenumber":"13345678888",        "address":"武汉市桥北医院北路"    }}
复制代码


我们可以使用如下的函数来处理:


def modifycustomer(request):
# 从请求消息中 获取修改客户的信息 # 找到该客户,并且进行修改操作 customerid = request.params['id'] newdata = request.params['newdata']
try: # 根据 id 从数据库中找到相应的客户记录 customer = Customer.objects.get(id=customerid) except Customer.DoesNotExist: return { 'ret': 1, 'msg': f'id 为`{customerid}`的客户不存在' }

if 'name' in newdata: customer.name = newdata['name'] if 'phonenumber' in newdata: customer.phonenumber = newdata['phonenumber'] if 'address' in newdata: customer.address = newdata['address']
# 注意,一定要执行save才能将修改信息保存到数据库 customer.save()
return JsonResponse({'ret': 0})
复制代码

七、删除客户

数据资源的 增查改删 里面的 删 就是 删除,对应的就是删除数据资源。根据接口文档,删除客户数据接口,前端只需要提供要删除的客户的 ID。数据格式如下:


{    "action":"del_customer",    "id": 6}
复制代码


我们可以使用如下的函数来处理:


def deletecustomer(request):
customerid = request.params['id']
try: # 根据 id 从数据库中找到相应的客户记录 customer = Customer.objects.get(id=customerid) except Customer.DoesNotExist: return { 'ret': 1, 'msg': f'id 为`{customerid}`的客户不存在' }
# delete 方法就将该记录从数据库中删除了 customer.delete()
return JsonResponse({'ret': 0})
复制代码

八、和前端集成

最终我们的产品 前端和后端系统会集成在一起成为一个完整的系统。部署到生产环境(生产环境就是正式的线上运营环境)运行的架构往往比较复杂。我们在后面有专门的章节讲述 一个比较完整的线上环境 如何搭建。



现在,请打开 bysms/urls.py 文件,在末尾 添加一个:


+  static("/", document_root="./z_dist")
复制代码


并添加如下声明


# 静态文件服务from django.conf.urls.static import static
复制代码


最终,内容如下:


from django.contrib import admin
# 导入一个include函数from django.urls import path, include
# 静态文件服务from django.conf.urls.static import static
urlpatterns = [ path('admin/', admin.site.urls),
# 凡是 url 以 sales/ 开头的, # 都根据 sales.urls 里面的 子路由表进行路由 path('sales/', include('sales.urls')),
# 凡是 url 以 api/mgr 开头的, # 都根据 mgr.urls 里面的 子路由表进行路由 path('api/mgr/', include('mgr.urls')),
] + static("/", document_root="./z_dist")
复制代码


最后的+ static("/", document_root="./z_dist")就是在 url 路由中加入 前端静态文件的查找路径。这样如果 http 请求的 url 不是以 admin/ sales/ api/mgr/ 开头, Django 就会认为是要访问 z_dist 目录下面的静态文件。


好了,现在我们 运行如下命令,启动 Django 开发服务器:


python manage.py runserver 0.0.0.0:8080
复制代码


然后我们打开浏览器,输入如下网址:


http://127.0.0.1:8080/mgr/index.html#/
复制代码



添加用户:



这是前端开发的 客户管理界面,可以在界面上进行客户的 增查改删操作, 这些操作会触发 API 请求发送给我们的后端服务。大家可以操作一下看看, 后端是否能够正确的响应。


⬇️⬇️ ⬇️ 商务合作|交流学习|粉丝福利|Python 全套资料⬇️ ⬇️ ⬇️ 欢迎联系~

用户头像

是Dream呀

关注

Python领域优质创作者 2021.03.30 加入

2021年度博客之星TOP100,2021年度领域TOP5 Python领域优质创作者,交流、合作、学习,欢迎私信我VX+++ 一万次悲伤,依然会有Dream,我一直在最温暖的地方等你!

评论

发布
暂无评论
开源一夏 | Python Web开发(八):后端开发中的增查改删处理_是Dream呀_InfoQ写作社区