mgr/medicine.py
mgr/k8s.py
mgr/medicine.py
一、冗余代码优化
1、添加公共函数目录
#在当前应用项目(mgr)下创建一个lib目录,并创建公共代码文件
lib
|-handler.py
2、修改K8S.py存量代码
#应用公共函数
from lib.handler import dispatcherBase
#当前函数所支持请求类型
Action2Handler = {
'list_customer': listcustomers,
'add_customer': addcustomer,
'modify_customer': modifycustomer,
'del_customer': deletecustomer,
}
def dispatcher(request):
return dispatcherBase(request, Action2Handler)
Django_demo/mgr/order.py
from django.http import JsonResponse
from django.db import transaction
from django.db.models import F
# 导入 Order 对象定义
from paas.models import Order,OrderMedicine
def addorder(request):
info = request.params['data']
# 从请求消息中 获取要添加订单的信息
# 并且插入到数据库中
with transaction.atomic():
new_order = Order.objects.create(name=info['name'], customer_id=info['customerid'])
batch = [OrderMedicine(order_id=new_order.id,medicine_id=mid,amount=1)
for mid in info['medicineids']]
# 在多对多关系表中 添加了 多条关联记录
OrderMedicine.objects.bulk_create(batch)
return JsonResponse({'ret': 0,'id':new_order.id})
def listorder(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = Order.objects \
.annotate(
customer_name=F('customer__name'),
medicines_name=F('medicines__name')
) \
.values(
'id','name','create_date','customer_name','medicines_name'
)
# 将 QuerySet 对象 转化为 list 类型
retlist = list(qs)
# 可能有 ID相同,药品不同的订单记录, 需要合并
newlist = []
id2order = {}
for one in retlist:
orderid = one['id']
if orderid not in id2order:
newlist.append(one)
id2order[orderid] = one
else:
id2order[orderid]['medicines_name'] += ' | ' + one['medicines_name']
return JsonResponse({'ret': 0, 'retlist': newlist})
##################################新的入口函数################################
#添加导入公共函数
from .lib.handler import dispatcherBase
#传入本地函数和方法
Action2Handler = {
'list_order': listorder,
'add_order': addorder,
}
#重新定义入口函数
def dispatcher(request):
return dispatcherBase(request, Action2Handler)
3、定义公共函数
Django_demo/mgr/lib/handler.py
import json
from django.http import JsonResponse
def dispatcherBase(request,action2HandlerTable):
# 根据session判断用户是否是登录的管理员用户
if 'usertype' not in request.session:
return JsonResponse({
'ret': 302,
'msg': '未登录',
'redirect': '/mgr/sign.html'},
status=302)
if request.session['usertype'] != 'mgr':
return JsonResponse({
'ret': 302,
'msg': '用户非mgr类型',
'redirect': '/mgr/sign.html'},
status=302)
# 将请求参数统一放入request 的 params 属性中,方便后续处理
# GET请求 参数 在 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']
print(action)
if action in action2HandlerTable:
handlerFunc = action2HandlerTable[action]
return handlerFunc(request)
else:
return JsonResponse({'ret': 1, 'msg': 'action参数错误'})
# 根据不同的action分派给不同的函数进行处理
action = request.params['action']
if action in action2HandlerTable:
handlerFunc = action2HandlerTable[action]
return handlerFunc(request)
4、测试请求
import requests,pprint
#添加认证
payload = {
'username': 'root',
'password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')
# 构建添加 客户信息的 消息体,是json格式
payload = {
"action":"list_order",
}
url='http://127.0.0.1:8000/api/mgr/orders/'
if set_cookie:
# 将Set-Cookie字段的值添加到请求头中
headers = {'Cookie': set_cookie}
# 发送请求给web服务
response = requests.post(url,json=payload,headers=headers)
pprint.pprint(response.json())
返回
{'ret': 0,
'retlist': [{'create_date': '2023-10-26T01:15:09.718Z',
'customer_name': 'zhangsan',
'id': 13,
'medicines_name': 'gmkl',
'name': '天山订单'},
{'create_date': '2023-10-26T01:14:29.897Z',
'customer_name': 'zhangsan',
'id': 12,
'medicines_name': 'gmkl',
'name': '天山订单'},
{'create_date': '2023-10-26T01:13:35.943Z',
'customer_name': 'zhangsan',
'id': 11,
'medicines_name': 'gmkl',
'name': 'ts'},
{'create_date': '2023-10-25T03:08:00Z',
'customer_name': 'zhangsan',
'id': 5,
'medicines_name': 'gmkl',
'name': 'test'}]}
5、补全其他案例
Django_demo/mgr/k8s.py
from django.http import JsonResponse
from paas.models import PaasInfo
def listcustomers(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = PaasInfo.objects.values()
# 将 QuerySet 对象 转化为 list 类型
# 否则不能 被 转化为 JSON 字符串
retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist})
def addcustomer(request):
info = request.params['data']
# 从请求消息中 获取要添加客户的信息
# 并且插入到数据库中
# 返回值 就是对应插入记录的对象
record = PaasInfo.objects.create(ClusterName=info['ClusterName'] ,
NodeSum=info['NodeSum'] ,
PrometheusAddress=info['PrometheusAddress'])
return JsonResponse({'ret': 0, 'id':record.id})
def modifycustomer(request):
# 从请求消息中 获取修改客户的信息
# 找到该客户,并且进行修改操作
customerid = request.params['id']
newdata = request.params['newdata']
print(customerid,newdata)
try:
# 根据 id 从数据库中找到相应的客户记录
customer = PaasInfo.objects.get(id=customerid)
except PaasInfo.DoesNotExist:
return {
'ret': 1,
'msg': f'id 为`{customerid}`的客户不存在'
}
if 'ClusterName' in newdata:
customer.ClusterName = newdata['ClusterName']
if 'NodeSum' in newdata:
customer.NodeSum = newdata['NodeSum']
if 'PrometheusAddress' in newdata:
customer.PrometheusAddress = newdata['PrometheusAddress']
# 注意,一定要执行save才能将修改信息保存到数据库
customer.save()
return JsonResponse({'ret': 0})
def deletecustomer(request):
customerid = request.params['id']
try:
# 根据 id 从数据库中找到相应的客户记录
customer = PaasInfo.objects.get(id=customerid)
except PaasInfo.DoesNotExist:
return {
'ret': 1,
'msg': f'id 为`{customerid}`的客户不存在'
}
# delete 方法就将该记录从数据库中删除了
customer.delete()
return JsonResponse({'ret': 0})
#重定义入口函数
from .lib.handler import dispatcherBase
Action2Handler = {
'list_customer': listcustomers,
'add_customer': addcustomer,
'modify_customer': modifycustomer,
'del_customer': deletecustomer,
}
def dispatcher(request):
return dispatcherBase(request, Action2Handler)
Django_demo/mgr/medicine.py
from django.http import JsonResponse
# 导入 Medicine 对象定义(这块可能显示模块导入不正常,忽略)
from paas.models import Medicine
import json
def listmedicine(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = Medicine.objects.values()
# 将 QuerySet 对象 转化为 list 类型
# 否则不能 被 转化为 JSON 字符串
retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist})
def addmedicine(request):
info = request.params['data']
# 从请求消息中 获取要添加客户的信息
# 并且插入到数据库中
medicine = Medicine.objects.create(name=info['name'] ,
sn=info['sn'] ,
desc=info['desc'])
return JsonResponse({'ret': 0, 'id':medicine.id})
def modifymedicine(request):
# 从请求消息中 获取修改客户的信息
# 找到该客户,并且进行修改操作
medicineid = request.params['id']
newdata = request.params['newdata']
try:
# 根据 id 从数据库中找到相应的客户记录
medicine = Medicine.objects.get(id=medicineid)
except Medicine.DoesNotExist:
return {
'ret': 1,
'msg': f'id 为`{medicineid}`的药品不存在'
}
if 'name' in newdata:
medicine.name = newdata['name']
if 'sn' in newdata:
medicine.sn = newdata['sn']
if 'desc' in newdata:
medicine.desc = newdata['desc']
# 注意,一定要执行save才能将修改信息保存到数据库
medicine.save()
return JsonResponse({'ret': 0})
def deletemedicine(request):
medicineid = request.params['id']
try:
# 根据 id 从数据库中找到相应的药品记录
medicine = Medicine.objects.get(id=medicineid)
except Medicine.DoesNotExist:
return {
'ret': 1,
'msg': f'id 为`{medicineid}`的客户不存在'
}
# delete 方法就将该记录从数据库中删除了
medicine.delete()
return JsonResponse({'ret': 0})
from .lib.handler import dispatcherBase
Action2Handler = {
'list_medicine': listmedicine,
'add_medicine': addmedicine,
'modify_medicine': modifymedicine,
'del_medicine': deletemedicine,
}
def dispatcher(request):
return dispatcherBase(request, Action2Handler)
Django_demo/mgr/urls.py
from django.urls import path
from .views import login
from .sign_in_out import signin,signout
#重定义路由名称
from .k8s import dispatcher as k8s
from .order import dispatcher as order
from .medicine import dispatcher as medicine
urlpatterns = [
path('customers/', k8s),
path('medicines/', medicine),
path('orders/', order),
path('signin', signin),
path('signout', signout),
path('login',login)
]
二、数据库冗余
def listorder(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = Order.objects\
.annotate(
customer_name=F('customer__name'),
medicines_name=F('medicines__name')
)\
.values(
'id','name','create_date','customer_name','medicines_name'
)
# 将 QuerySet 对象 转化为 list 类型
retlist = list(qs)
# 可能有 ID相同,药品不同的订单记录, 需要合并
newlist = []
id2order = {}
for one in retlist:
orderid = one['id']
if orderid not in id2order:
newlist.append(one)
id2order[orderid] = one
else:
id2order[orderid]['medicines_name'] += ' | ' + one['medicines_name']
return JsonResponse({'ret': 0, 'retlist': newlist})
1、冗余问题思路
Django_demo/paas/models.py
class Order(models.Model):
# 订单名
name = models.CharField(max_length=200,null=True,blank=True)
# 创建日期
create_date = models.DateTimeField(default=datetime.datetime.now)
# 客户
customer = models.ForeignKey(Customer,on_delete=models.PROTECT)
# 订单购买的药品,和Medicine表是多对多 的关系
medicines = models.ManyToManyField(Medicine, through='OrderMedicine')
# 为了提高效率,这里存放 订单 medicines 冗余数据
medicinelist = models.CharField(max_length=2000,null=True,blank=True)
[
{"id": 1, "name": "青霉素", "amount": 20},
{"id": 2, "name": "来适可", "amount": 100}
]
id 表示药品的id
name 表示 药品的名字
amount 表示 药品的数量
python manage.py makemigrations common
python manage.py migrate
2、修改接口参数
{
"action":"add_order",
"data":{
"name":"华山医院订单002",
"customerid":3,
"medicineids":[1,2]
}
}
3、修改请求api格式
添加订单格式
{
"action":"add_order",
"data":{
"name":"华山医院订单002",
"customerid":3,
"medicinelist":[
{"id":16,"amount":5,"name":"环丙沙星"},
{"id":15,"amount":5,"name":"克林霉素"}
]
}
}
列出订单格式
{
"id": 2,
"name": "华山医院订单002",
"create_date": "2018-12-27T14:10:37.208Z",
"customer_name": "华山医院",
"medicinelist":[
{"id":16,"amount":5,"name":"环丙沙星"},
{"id":15,"amount":5,"name":"克林霉素"}
]
}
4、修改后端代码逻辑
修改添加逻辑
Django_demo/mgr/order.py
def addorder(request):
info = request.params['data']
with transaction.atomic():
medicinelist = info['medicinelist']
new_order = Order.objects.create(name=info['name'],
customer_id=info['customerid'],
# 写入json格式的药品数据到 medicinelist 字段中
medicinelist=json.dumps(medicinelist,ensure_ascii=False),)
batch = [OrderMedicine(order_id=new_order.id,
medicine_id=medicine['id'],
amount=medicine['amount'])
for medicine in medicinelist]
OrderMedicine.objects.bulk_create(batch)
return JsonResponse({'ret': 0, 'id': new_order.id})
修改列出表逻辑
Django_demo/mgr/order.py
def listorder(request):
qs = Order.objects \
.annotate(
customer_name=F('customer__name')
)\
.values(
'id', 'name', 'create_date',
'customer_name',
'medicinelist'
)
# 将 QuerySet 对象 转化为 list 类型
retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist})
5、添加数据
import requests,pprint
#添加认证
payload = {
'username': 'root',
'password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')
# 构建添加 客户信息的 消息体,是json格式
payload = {
"action":"add_order",
"data":{
"name":"华山医院订单002",
"customerid":1,
"medicinelist":[
{"id":6,"amount":5,"name":"gmkl"},
]
}
}
url='http://127.0.0.1:8000/api/mgr/orders/'
if set_cookie:
# 将Set-Cookie字段的值添加到请求头中
headers = {'Cookie': set_cookie}
# 发送请求给web服务
response = requests.post(url,json=payload,headers=headers)
print(response)
注意
payload = {
"action":"add_order",
"data":{
"name":"华山医院订单002",
"customerid":1,
"medicinelist":[
{"id":6,"amount":5,"name":"gmkl"},
]
}
}
6、调用查询数据
import requests,pprint
#添加认证
payload = {
'username': 'root',
'password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')
# 构建添加 客户信息的 消息体,是json格式
payload = {
"action":"list_order",
"data":{
"customer_name":"华山医院订单002",
}
}
url='http://127.0.0.1:8000/api/mgr/orders/'
if set_cookie:
# 将Set-Cookie字段的值添加到请求头中
headers = {'Cookie': set_cookie}
# 发送请求给web服务
response = requests.post(url,json=payload,headers=headers)
pprint.pprint(response.json())
返回
{'create_date': '2023-11-02T09:05:27.095Z',
'customer_name': 'zhangsan',
'id': 19,
'medicinelist': '[{"id": 6, "amount": 5, "name": "gmkl"}]',
'name': '华山医院订单002'}]}