文章目录
BYSMS
bysms
setting.py
"""
Django settings for bysms project.
Generated by 'django-admin startproject' using Django 2.1.3.
For more information on this file, see
https://docs.djangoproject.com/en/2.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.1/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '%0r0r7w-%m+7=h05-0e=k(7gjx@k+%xc5869!5&5ld$+4^iqqx'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'common.apps.CommonConfig',#添加一个应用的配置类
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',#临时注销CSRF校验
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
]
ROOT_URLCONF = 'bysms.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'bysms.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',#默认使用sqlite3数据库
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
urls.py
from django.contrib import admin
from django.urls import path,include#path用于指定路径,include用于包裹二级路由
from sales.views import listcustomers#将可调用方法导入以便对应URL指定
from django.conf.urls.static import static#静态服务声明
urlpatterns = [
path('admin/', admin.site.urls),#http://127.0.0.1/admin/指向Django Admin管理平台
path('sales/customers/', listcustomers),#一级路由,路径sales/customers/直接指定到可调用方法
path('api/mgr/',include('mgr.urls'))#指定二级路由,路径以api/mgr/开头的,去查找mgr包下面的urls文件
]+ static("/", document_root="./z_dist")#指向静态文件路径
wsgi.py
commom
admin.py
from django.contrib import admin
# Register your models here.
from .models import Customer
admin.site.register(Customer)#将Customer表注册到admin,可以进行admin管理
apps.py
models.py
from django.db import models
import datetime
# Create your models here.
class Customer(models.Model):
#客户名称
name=models.CharField(max_length=200)#varchar
#电话
phonenumber=models.CharField(max_length=200)
#地址
address=models.CharField(max_length=200)
#from django.contrib import admin
#admin.site.register(Customer)
#效果同admin.py文件中注册代码效果一致
class Medicine(models.Model):
# 药品名
name = models.CharField(max_length=200)
# 药品编号
sn = models.CharField(max_length=200)
# 描述
desc = models.CharField(max_length=200)
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)#多对一外键,关联到Customer表的主键,在库表中自动创建的名称是customer_id
# 订单购买的药品,和Medicine表是多对多 的关系,一个订单有多个药品,一个药品也能在多个订单中
medicines = models.ManyToManyField(Medicine, through='OrderMedicine')#不在数据库的Order中显示
class OrderMedicine(models.Model):#用于指代多对多的明细表
order = models.ForeignKey(Order, on_delete=models.PROTECT)#在库表中自动创建的名称是order_id
medicine = models.ForeignKey(Medicine, on_delete=models.PROTECT)#在库表中自动创建的名称是medicine_id
# 订单中药品的数量
amount = models.PositiveIntegerField()
mgr
urls.py
from django.urls import path
from mgr import sign_in_out_view,tocustomer_view,tomedicine_view,toorder_view#导入可调用方法
urlpatterns = [
path('signin', sign_in_out_view.signin),
path('signout', sign_in_out_view.signout),
path('customers', tocustomer_view.dispatcher),
path('medicines', tomedicine_view.dispatcher),
path('orders', toorder_view.dispatcher),
]
sign_in_out_view.py
from django.http import JsonResponse#一个用于接收一个request对象后返回jsonresponse的类
from django.contrib.auth import authenticate, login, logout#验证、登入、登出
# 登录处理
def signin( request):
# 从 HTTP POST 请求中获取用户名、密码参数request.POST.get(),request.POST消息体
userName = request.POST.get('username')
passWord = request.POST.get('password')
# 使用 Django auth 库里面的 方法校验用户名、密码(去auth_user表里去找)
user = authenticate(username=userName, password=passWord)
# 如果能找到用户,并且密码正确
if user is not None:#是否存在
if user.is_active:#是否active(auth_user表中is_active字段)
if user.is_superuser:#是否超级用户|管理员(auth_user表中is_staff字段)
login(request, user)#login登录操作,也会更新表中时间等信息
# 在session中存入用户类型用于以后session校验
request.session['usertype'] = 'mgr'
return JsonResponse({'ret': 0})
else:
return JsonResponse({'ret': 1, 'msg': '请使用管理员账户登录'})
else:
return JsonResponse({'ret': 0, 'msg': '用户已经被禁用'})
# 否则就是用户名、密码有误
else:
return JsonResponse({'ret': 1, 'msg': '用户名或者密码错误'})
# 登出处理
def signout( request):
# 使用登出方法
logout(request)
return JsonResponse({'ret': 0})
tocustomer_view.py
from django.http import JsonResponse #相应类型是json格式内容,导入JsonResponse
import json #需要json工具解析
from common.models import Customer #找到要梳理的数据表
def dispatcher(request):
#session鉴权
#没有登录
if 'usertype' not in request.session:#django给传入的request添加session属性,就是django_session表的session_data键
return JsonResponse({
'ret': 302,#302重定向
'msg': '未登录',
'redirect': '/mgr/sign.html'}, #重定向地址
status=302)
#非管理员
if request.session['usertype'] != 'mgr' :
return JsonResponse({
'ret': 302,
'msg': '用户非mgr类型',
'redirect': '/mgr/sign.html'} ,#非mgr也重定向
status=302)
#根据不同请求方式给request.params赋值
if request.method =='GET':#如果request的方法是‘get’,那就将request的GET属性所有内容放入params里面
request.params=request.GET#类似字典,将请求参数放入request的params属性中,方便后续处理
elif request.method in ['POST','DELETE','PUT']:#如果是这几类请求方式,请求体是在body里面
request.params=json.loads(request.body)#获取的body是json,解析后类似字典
#根据request的action参数,分别制定处理方法(具体需要事先阅读API需求文动能)
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请求'})
##from common.models import Customer #先找到数据表,放最上面
#1.list_customer:根据api,响应的返回结果是个字典样式的json对象
def listcustomers(request):
qs=Customer.objects.values()#qs是Queryset类似一个字典列表,同响应内容的‘relist'的value格式一致
relist=list(qs)#类型转换下,否则不能转化成json字符串
return JsonResponse({'ret':0,'relist':relist})
#2.add_customer:从request中获取要添加的数据,再加到表中
def addcustomer(request):
info=request.params['data']#从request.params获取数据,又是一个字典
record=Customer.objects.create(name=info['name'],
phonenumber=info['phonenumber'],
address=info['address'])#create方法往Customer表中添加数据,并返回动态生成的id
return JsonResponse({'ret': 0, 'id':record.id}) #返回记录的id
#3.modify_customer:从request中获取要添加的数据,再加到表中
def modifycustomer(request):
newinfo=request.params['newdata']#从request.params获取数据,又是一个字典
customerid=request.params['id']#获取request中传入的id
try:
record=Customer.objects.get(id=customerid)#get方法先在表中查找是否有该id的记录
except Customer.DoesNotExist:
return JsonResponse({'ret':1,'msg':f'id为`{customerid}`的客户不存在'})#没找到就返回信息
#找到后对该record进行修改
if 'name' in newinfo:#一条记录有可能并非所有字段都要修改,不需要修改的就没传入
record.name=newinfo['name']
if 'phonenumber' in newinfo:
record.phonenumber=newinfo['phonenumber']
if 'address' in newinfo:
record.address=newinfo['address']#往Customer表中添加数据,并返回动态生成的id
#修改后记录要保存下
record.save()
return JsonResponse({'ret':0})
#4.delete_customer:从request中获取id,查找到record后删除
def deleteCustomer(request):
customerid=request.params['id']#获取request中传入的id
try:
record=Customer.objects.get(id=customerid)#get方法先在表中查找是否有该id的记录
except Customer.DoesNotExist:
return JsonResponse({'ret':1,'msg':f'id为`{customerid}`的客户不存在'})#没找到就返回信息
#找到后就删除该条记录
record.delete()
return JsonResponse({'ret':0})
tomedicine_view.py(与tocustomer_view.py类似)
from django.http import JsonResponse #相应类型是json格式内容,导入JsonResponse
import json #需要json工具
from common.models import Medicine #找到数据表
from django.http import JsonResponse #相应类型是json格式内容,导入JsonResponse
import json #需要json工具
from common.models import Medicine #找到数据表
def dispatcher(request):
'''
#没有登录
if 'usertype' not in request.session:#django给传入的request添加session属性,就是django_session表的session_data键
return JsonResponse({
'ret': 302,#302重定向
'msg': '未登录',
'redirect': '/mgr/sign.html'}, #重定向地址
status=302)
#非管理员
if request.session['usertype'] != 'mgr' :
return JsonResponse({
'ret': 302,
'msg': '用户非mgr类型',
'redirect': '/mgr/sign.html'} ,#非mgr也重定向
status=302)
'''
if request.method =='GET':#如果request的方法是‘get’,那就将request的GET属性放入params里面
request.params=request.GET#类似字典,将请求参数放入request的params属性中,方便后续处理
elif request.method in ['POST','DELETE','PUT']:#如果是这几类请求方式,请求体是在body里面,且是json格式
request.params=json.loads(request.body)#解析后类似字典
#根据request的action参数,分别制定处理方法(具体需要事先阅读API需求文动能)
action=request.params['action']
if action=='list_medicine':
return listmedicine(request)
elif action=='add_medicine':
return addmedicine(request)
elif action=='modify_medicine':
return modifymedicine(request)
elif action=='del_medicine':
return deletemedicine(request)
else:
return JsonResponse({'ret':1,'msg':'不支持该类型的http请求'})
##from common.models import Medicine #先找到数据表,放最上面
#1.list_customer:根据api,响应的返回结果是个字典样式的json对象
def listmedicine(request):
qs=Medicine.objects.values()#qs是Queryset类似一个字典列表,同响应内容的‘relist'的value格式一致
relist=list(qs)#类型转换下,否则不能转化成json字符串
return JsonResponse({'ret':0,'relist':relist})
#2.add_customer:从request中获取要添加的数据,再加到表中
def addmedicine(request):
info=request.params['data']#从request.params获取数据,又是一个字典
record=Medicine.objects.create(name=info['name'],
sn=info['sn'],
desc=info['desc'])#create方法往Medicine表中添加数据,并返回动态生成的id
return JsonResponse({'ret': 0, 'id':record.id}) #返回记录的id
#3.modify_customer:从request中获取要添加的数据,再加到表中
def modifymedicine(request):
newinfo=request.params['newdata']#从request.params获取数据,又是一个字典
medicineid=request.params['id']#获取request中传入的id
try:
record=Medicine.objects.get(id=medicineid)#get方法先在表中查找是否有该id的记录
except Medicine.DoesNotExist:
return JsonResponse({'ret':1,'msg':f'id为`{medicineid}`的药品不存在'})#没找到就返回信息
#找到后对该record进行修改
if 'name' in newinfo:
record.name=newinfo['name']
if 'sn' in newinfo:
record.sn=newinfo['sn']
if 'desc' in newinfo:
record.desc=newinfo['desc']#往Customer表中添加数据,并返回动态生成的id
#修改后记录要保存下
record.save()
return JsonResponse({'ret':0})
#4.delete_customer:从request中获取id,查找到record后删除
def deletemedicine(request):
medicineid=request.params['id']#获取request中传入的id
try:
record=Medicine.objects.get(id=medicineid)#get方法先在表中查找是否有该id的记录
except Medicine.DoesNotExist:
return JsonResponse({'ret':1,'msg':f'id为`{medicineid}`的药品不存在'})#没找到就返回信息
#找到后就删除该条记录
record.delete()
return JsonResponse({'ret':0})
toorder_view.py
from django.http import JsonResponse #相应类型是json格式内容,导入JsonResponse
import json #需要json工具
from common.models import Order,OrderMedicine #找到数据表
from django.db.models import F
from django.db import IntegrityError,transaction
def dispatcher(request):
'''
#没有登录
if 'usertype' not in request.session:#django给传入的request添加session属性,就是django_session表的session_data键
return JsonResponse({
'ret': 302,#302重定向
'msg': '未登录',
'redirect': '/mgr/sign.html'}, #重定向地址
status=302)
#非管理员
if request.session['usertype'] != 'mgr' :
return JsonResponse({
'ret': 302,
'msg': '用户非mgr类型',
'redirect': '/mgr/sign.html'} ,#非mgr也重定向
status=302)
'''
if request.method =='GET':#如果request的方法是‘get’,那就将request的GET属性放入params里面
request.params=request.GET#类似字典,将请求参数放入request的params属性中,方便后续处理
elif request.method in ['POST','DELETE','PUT']:#如果是这几类请求方式,请求体是在body里面,且是json格式
request.params=json.loads(request.body)#解析后类似字典
#根据request的action参数,分别制定处理方法(具体需要事先阅读API需求文动能)
action=request.params['action']
if action=='list_order':
return listorder(request)
elif action=='add_order':
return addorder(request)
else:
return JsonResponse({'ret':1,'msg':'不支持该类型的http请求'})
'''
def addorder(request):
info = request.params['data']
# 从请求消息中 获取要添加订单的信息
# 并且插入到数据库中
new_order = Order.objects.create(name=info['name'] ,
customer_id=info['customerid'])
OrderMedicine.objects.create(order_id=new_order.id,medicine_id=info['medicineids'],amount=1)
return JsonResponse({'ret': 0,'id':new_order.id})
'''
#2.add_order:从request中获取要添加的数据,再加到表中
def addorder(request):
info=request.params['data']#从request.params获取数据,又是一个字典
with transaction.atomic():#事务自动回滚
record=Order.objects.create(name=info['name'],#create_date已经在建表的时候定义好了等于当前时间
customer_id=info['customerid'])#create方法往Order表中添加数据,并返回动态生成的id
batch=[OrderMedicine(order_id=record.id,medicine_id=mid,amount=1) for mid in info['medicineids']]#使用序列推导将medicines列表中的记录取出来
#这里OrderMedicine表中的order_id就是Order表中心插入record自动生成的id
OrderMedicine.objects.bulk_create(batch)#bulk_create批量创建记录
return JsonResponse({'ret': 0, 'id':record.id}) #返回记录的id
def listorder(request):
qs = Order.objects \
.annotate(
customer_name=F('customer__name'),#从本表的customer字段的关联表的name字段,并取别名
medicines_name=F('medicines__name')#从本表的medicines字段的关联表的name字段,并取别名
)\
.values(
'id', 'name', 'create_date',
# 两个下划线,表示取customer外键关联的表中的name字段的值
'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})
sales
apps.py
views.py
1.简单自定义字符串格式
from django.shortcuts import render
from django.http import HttpResponse#一个用于接收一个request对象后返回httpresponse的类
from common.models import Customer#将要处理数据的表导入
# Create your views here.
#1.简单自定义字符串格式
def listcustomers(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
# 每条表记录都是是一个dict对象,
# key 是字段名,value 是 字段值
qs = Customer.objects.values()
# 检查url中是否有参数phonenumber
ph = request.GET.get('phonenumber',None)
# 如果有,添加过滤条件
if ph:
qs = qs.filter(phonenumber=ph)
## 定义返回字符串
retStr = ''
for customer in qs:
for name,value in customer.items():
retStr += f'{name} : {value} | '
# <br> 表示换行
retStr += '<br>'
return HttpResponse(retStr)
2.使用模板字符串
html_template ='''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
table {
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<table>
<tr>
<th>id</th>
<th>姓名</th>
<th>电话号码</th>
<th>地址</th>
</tr>
%s
</table>
</body>
</html>
'''
#2.使用模板
def listcustomers(request):
qs=Customer.objects.values()
ph=request.GET.get('phonenumber',None)
if ph:
qs=qs.filter(phonenumber=ph)
##字符串模板
tableContent=''
for customer in qs:
tableContent+='<tr>'#开启一行
for name,value in customer.items():
tableContent+=f'<td>{value}</td>'#一个单元格
tableContent+='</tr>'#结束一行
return HttpResponse(html_template % tableContent)#返回html模板化后的字符串,替代模板中的%s
3.使用模板引擎
html_template1 ='''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
table {
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid #ddd;
}
</style>
</head>
<body>
<table>
<tr>
<th><font color="red">id</font></th>
<th>姓名</th>
<th>电话号码</th>
<th>地址</th>
</tr>
{% for customer in customers %}
<tr>
{% for name, value in customer.items %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
</body>
</html>
#3.模板引擎
from django.template import engines #导入模板引擎
django_engine=engines['django'] #创建一个django的引擎
template = django_engine.from_string(html_template1)#创建一个模板对象来自html_template1
def listcustomers(request):
qs = Customer.objects.values()
ph = request.GET.get('phonenumber',None)
if ph:
qs = qs.filter(phonenumber=ph)
rendered = template.render({'customers':qs}) #qs就是要传入的中的customers
return HttpResponse(rendered)
tests
tc001.py
import requests,pprint
#sign_in_out_view测试
url='http://127.0.0.1/api/mgr/signin'
body={'username': 'mx',
'password': 'mx123456'}
response=requests.post(url,data=body)
pprint.pprint(response.json())
tc002.py
import requests,pprint
#tocustomer_view测试
url='http://127.0.0.1/api/mgr/customers'
##list_customer列出客户
params={'action':'list_customer'}
response=requests.get(url,params)
pprint.pprint(response.json())
##add_customer添加用户
body={'action':'add_customer',
'data':{'name':'武汉市桥西医院',
'phonenumber':'13345679934',
'address':'武汉市桥西医院北路'}
}
response=requests.post(url,json=body)#body作为json传进去,views.py中对应可调用方法就是把它当做json然后解析的
pprint.pprint(response.json())
##modify_customer修改用户
body={"action":"modify_customer",
"id": 2,
"newdata":{
"phonenumber":"13345676666",
"address":"武汉市桥北医院南路"}
}
response=requests.put(url,json=body)#body作为json传进去,因为对应可调用发发就是把它当做json
pprint.pprint(response.json())
##delete_customer删除用户
body={"action":"del_customer",
"id": 6}
response=requests.delete(url,json=body)#body作为json传进去,因为对应可调用方法就是把它当做json
pprint.pprint(response.json())
tc003.py
import requests,pprint
#tomedicine_view测试
url='http://127.0.0.1/api/mgr/medicines'
##list_medicine列出
'''
params={'action':'list_medicine'}
response=requests.get(url,params)
pprint.pprint(response.json())
'''
##add_medicine添加
body={'action':'add_medicine',
'data':{'name':'红霉素',
'sn':'22345678',
'desc':'红霉素'}
}
response=requests.post(url,json=body)#body作为json传进去,因为对应可调用发发就是把它当做json
pprint.pprint(response.json())
##modify_medicine修改
'''
body={"action":"modify_medicine",
"id": 2,
"newdata":{"name":"红霉素",
"sn":"22345678",
"desc":"红霉素"}
}
response=requests.put(url,json=body)#body作为json传进去,因为对应可调用发发就是把它当做json
pprint.pprint(response.json())
'''
##delete_medicine删除
'''
body={"action":"del_medicine",
"id": 2}
response=requests.delete(url,json=body)#body作为json传进去,因为对应可调用方法就是把它当做json
pprint.pprint(response.json())
'''
tc004.py
import requests,pprint
#order_view测试
url='http://127.0.0.1/api/mgr/orders'
'''
#列出订单
params={'action':'list_order'}
response=requests.get(url,params)
pprint.pprint(response.json())
'''
#添加订单
body={
"action":"add_order",
"data":{
"name":"华山医院订单003",
"customerid":2,
"medicineids":[1,2]
}
}
response=requests.post(url,json=body)#body作为json传进去,因为对应可调用发发就是把它当做json
pprint.pprint(response.json())