文章目錄
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())