先运行WIN+R、输入CMD
然后切换到D盘、输入D:
还要去pycharm的设置里添加django
然后输入以下命令django-admin startproject mydjango
然后我们打开D盘看看是不是有个叫mydjango的文件夹
这里面都有python文件
再返回CMD、开启服务器、端口:python manage.py runserver 8080、端口8080随便自已设
还有一种命令是:python manage.py runserver 0.0.0.0:8080这个命令是默认本机的所有可用IP地址、打开网址的时候可以直接输入本机的IP地址做为服务器地址、还需要在setting.py文件中的
ALLOWED_HOSTS=['192.168.6.66']添加本机的IP、还有localhost:8080也是本地
看到下面的红框里的代表服务器启动完毕、端口号自已随便设
后面是添加应用
先运行CMD、然后进入D盘、然后进mydjango文件夹、然后输入以下命令python manage.py startapp first
也可以在IDE直接执行命令:看下面第2张图、sales跟first都是目录文件名、自已可以随便改
后面是创建视图
创建完视图、就要配置URL、要先from sales import views
注意:输入网址前要记得在CMD中开启服务器:python manage.py runserver 6161
以下三张图的2级路由可以忽略不看、有必要再看
四、创建数据库
执行命令:python manage.py migrate 、相当于在数据库创建了表
五、打开数据库文件、先去网站下载一个可以查看数据库文件的软件:点下方SQLiteStudiohttps://sqlitestudio.pl/
也可以用(Navicat)软件
六、创建修改数据库的common文件、与sales文件一样的、然后要在modelss.py这个文件操作
输入这几行代码、创建类、继承对应的字段型
然后还要在setting.py文件中添加这个应用(common)的路径:common.apps.CommonConfig
当然前面还添加了一个sales的应用也是可以添加进去的、只是现在用不上
有任何的修改都要去CMD执行命令:python manage.py makemigrations common
这个命令是、如果有更新文件、就刷新这个命令
这个命令,告诉Django , 去看看common这个app里面的models.py ,我们已经修改了数据定义, 你现在去产生相应的更新脚本。
执行一下,会发现在 common\migrations 目录下面出现了0001_initial.py, 这个脚本就是相应要进行的数据库操作代码。
然后就是CMD执行:python manage.py migrate
这个命令是去数据库创建表、就是创建上面001这个文件里的name=costomer这个表
如果上面文件添加了某些字段或代码、刷新完了之后、再执行这个命令更新到数据库中
接下来要给数据库创建超级管理员帐户,进入CMD输入:python manage.py createsuperuser
然后依次输入帐户、邮箱、密码
然后我们需要修改应用里面的 管理员 配置文件 common/admin.py,注册我们定义的model类。这样Django才会知道
from django.contrib import admin
from .models import Customer
admin.site.register(Customer)
下面这个表中就是我们刚建的超级管理员帐户
下面再把刚刚建的客户名称那个表体现在网站上,下面这个页面上的是后台管理、但是别人看你们的网站上是views这个文件里的内容、模板
我们再把之前演示的URLS的路径删了、删了的不用管
下面设置第二个路径sales怎么把数据库的字段名、数据体现在网站上
先在sales文件夹下的views文件写入以下代码:
from django.shortcuts import render
from django.http import HttpResponse
# 导入 Customer 对象定义
from common.models import Customer
def listcustomers(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
# 每条表记录都是是一个dict对象,
# key 是字段名,value 是 字段值
qs = Customer.objects.values()
# 定义返回字符串
retStr = '' #占位符
for customer in qs:
for name,value in customer.items(): #遍历数据库中customer表中的name(字段名)、value(字段值)这里不是字段的名字
retStr += f'{name} : {value} | ' #f是format格式化字符串,那后面的|是什么意思呢、是字段的间隔、每次遍历后就会隔开
#
表示换行
retStr += '
' #br是html的换行、以html的形式返回
return HttpResponse(retStr) #最后就是定义的retstr值返回到html里
下面打开网址:
上面那种显示格式不好看、我们再改一下网页内容的格式、以单元格的形式显示
from django.shortcuts import render
from django.http import HttpResponse
# 导入 Customer 对象定义
from common.models import Customer
html_table='''
id
姓名
电话号码
地址
QQ
%s
'''
#是头部,是html里的表,是换行的意思,是表头(也就是字段名),最后%s是什么意思、这个是填充的意思、从数据库填充数据、python最后的代码返回数据填充在这里
def listcustomers(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
# 每条表记录都是是一个dict对象(字典),
# key 是字段名,value 是 字段值
qs = Customer.objects.values()
ph=request.GET.get('qq',None) #大写的GET代表请求、get小写的方法,如果请求的字段有值就返回值、没有就返回None
if ph:
qs=qs.filter(qq=ph) #用filter过滤方法、如果ph有查询出来值就返回给qs、然后返回到网页上
tableContent=''
for customer in qs:
tableContent +=' '
for name,value in customer.items():
tableContent +=f'{value} '
tableContent +=' '
# # 定义返回字符串
# retStr = '' #占位符
# for customer in qs:
# for name,value in customer.items(): #遍历数据库中customer表中的name(字段名)、value(字段值)这里不是字段的名字
# retStr += f'{name} : {value} | ' #f是format格式化字符串,那后面的|是什么意思呢、是字段的间隔、每次遍历后就会隔开
#
# #
表示换行
# retStr += '
' #
是html的换行、以html的形式返回、+=是复合运算符
return HttpResponse(html_table % tableContent) #最后就是定义的retstr值返回到html里
这样是不是就好看多了
还可以用HTML模板形式来喧染、下面是代码
from django.shortcuts import render
from django.http import HttpResponse
# 导入 Customer 对象定义
from common.models import Customer
# 先定义好HTML模板
html_template = '''
id
姓名
电话号码
地址
{% for customer in customers %}
{% for name, value in customer.items %}
{{ value }}
{% endfor %}
{% endfor %}
'''
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string(html_template)
def listcustomers(request):
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = Customer.objects.values()
# 检查url中是否有参数phonenumber
ph = request.GET.get('phonenumber', None)
# 如果有,添加过滤条件
if ph:
qs = qs.filter(phonenumber=ph)
# 传入渲染模板需要的参数
rendered = template.render({'customers': qs})
return HttpResponse(rendered)
前面我们已经为 销售员用户 专门创建了一个应用 sales 来处理相关的 请求。
所以,我们可以 再为 管理员用户 专门创建一个应用 mgr 来处理相关的 请求。 怎么创建还记得吗?
对了,执行
python manage.py startapp mgr
我是直接用pycharm编辑器里的终端来执行命令的、也可以在CMD执行
创建mgr 这个APP后、还要再建一个customer.py文件
import json
from django.http import JsonResponse
from common.models import Customer
import common.models
def dispatcher(request):
# 将请求参数统一放入request的params属性中,方便后续处理
# GET请求 参数在url中,同时request对象的GET属性获取
if request.method == 'GET':
request.params = request.GET
# POST/PUT/DELETE(添加、修改、删除、上面GET是查询)4种请求参数从request对象的body属性中获取
elif request.method in ['POST', 'PUT', 'DELETE']:
# 根据接品、POST/PUT/DETELE请求的消息体都是json格式
request.params = json.loads(request.body)
# 根据不同的action分派给不同的函数进行处理
action = request.params['action']
if action == 'list_customer': #如果{action:list_customer}就执行listcustomers函数
return listcustomers() # 列出客户函数、这个函数在下面创建
elif action == 'add_customer':
return addcustomers(request) # 添加客户函数
elif action == 'modify_customer':
return modifycustomer(request) # 修改客户函数
elif action == 'del_customer':
return deletecustomer(request) # 删除客户函数
else:
return JsonResponse({'ret': 1, 'msg': '不支持该类型的http请求'})
#查询API
def listcustomers():
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = common.models.Customer.objects.values() # 这个函数是从common这个APP里的models.py文件里的类属性、也可以用from\import先导入APP
# 然后把上面的类属性转化为list(列表)、否则不能在网页上转化为json字符串
retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist}) # 返回给接口里的那2个字典元素、分别是ret、retlist(上面转化为listr的变量)
#添加API
def addcustomers(request):
info = request.params['data']
# 从请求消息中获取要添加客户的信息
# 并且插入到数据库中
# 返回值就是对应插入记录的对象
record = common.models.Customer.objects.create(name=info['name'], # 这个函数是从common这个APP里的models.py文件里的类属性\每个字段对应这个类里的变量
phonenumber=info['phonenumber'],
address=info['address']
)
return JsonResponse({'ret': 0, 'id': record.id}) # 返回给接口的那2个字典元素,分别是ret、id(因为ID是动态自增长的、又要返回上面的变量).点name就是name这个字段
#修改API
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})
#删除API
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})
注意上面
addcustomers函数里的ID是缺省字段,缺省创建的项目, Django 会启用一个 CSRF (跨站请求伪造) 安全防护机制。
在这种情况下, 所有的Post、PUT 类型的 请求都必须在HTTP请求头中携带用于校验的数据。
为了简单起见,我们先临时取消掉CSRF的 校验机制,等以后有需要再打开。
要临时取消掉CSRF的 校验机制,非常简单,只需要在 项目的配置文件 bysms/settings.py
中 MIDDLEWARE
配置项 里 注释掉 ‘django.middleware.csrf.CsrfViewMiddleware’ 即可。
接下来就要跟前端做集成了、先按这个地址下载文件:https://cdn2.byhy.net/files/django/z_dist.zip
下载的文件一定要放在项目的目录上,然后解压
因为我现在用的是django的开发服务器、我们还没有WEB服务器、不能直接调用上面的下载的文件、我们还要做一些配置
但是前端文件都是静态文件,需要我们配置一下Django的配置文件, 指定http请求如果访问静态文件,Django在哪个目录下查找。
注意,接下来我们配置 Django 静态文件服务, 是 开发时
使用的 一种 临时方案
,性能很低,这是方便我们调试程序用的。
前面讲过,正式部署web服务的时候,不应该这样干,应该采用其它方法,比如Nginx等。后面的教程会有详细的讲解如何使用Nginx 和 Django 组合使用。
现在,请打开 mydjango/urls.py
文件,在末尾 添加一个
+ static("/", document_root="./z_dist")
并添加如下声明
# 静态文件服务
from django.conf.urls.static import static
django的urls匹配都是按顺序来的、如果上面的三个url没有匹配到、就执行最后的代码
最后的代码是前面下载的APP路径、path路径开头都不能有/反斜杠
输入以下网址:
http://127.0.0.1:8085/mgr/index.html
记得启动django服务器:python manage.py runserver 0.0.0.0:8085
注意:如果你打开上面的网址是空白的、要解决这个问题,请在 Django项目 setting.py 中 末尾添加如下代码,强制Django使用’application/javascript' 作为 js文件类型
import mimetypes
mimetypes.add_type('text/css', '.css')
mimetypes.add_type('application/javascript', '.js')
前面我们 实现了 服务端 管理员 的一些增删改查操作,但是,我们还没有实现管理员 登录的功能呢。
现在我们来根据,API接口文档, 点击这里查看 实现 管理员登录 功能。
先在mgr这个APP下创建py文件
输入以下代码:
from django.http import JsonResponse
from django.contrib.auth import authenticate,login,logout
# 登录处理
def signin(request):
userName=request.POST.get('username')
passWord=request.POST.get('password') #从http、post中提取数据库中存放用户名的字段、帐户与密码
user=authenticate(username=userName,password=passWord) #然后用django中自带的与数据库的帐户密码校验方法、帐户对应帐户、密码对应密码
#如果能找到帐户与密码、就登录成功、反回0
if user is not None:
if user.is_active: #对应的数据库字段、如果字段下是1就是正常使用用户、如果是0就是禁用用户
if user.is_superuser: #对应的数据库字段、如果字段下是1就是管理员
login(request,user) #这个login就是登录进去了、下面就是返回0
request.session['usertype']='mgr' #这个session是对应的数据库的表、这个表是保存用户的登录信息
return JsonResponse({'ret':0,'msg':'登录成功'})
else:
return JsonResponse({'ret':1,'msg':'请用管理员用户登录'})
else:
return JsonResponse({'ret':1,'msg':'帐户已被禁用'})
else:
return JsonResponse({'ret':1,'msg':'帐户或密码错误,请重新输入'})
#退出处理
def sinout(request):
logout(request) #logout这个函数是http中用户登录后退出的方法
return JsonResponse({'ret':0,'msg':'你已退出'})
登录与退出的API创建好了后、我们还要设置USRL路径
上面的是主路由设置、凡是api/mgr这个路径为开头的、都由mgr这个APP下的URL路径来执行
上面测试了一下直接下载的前端应用、那如果没有前端应用的话要怎么测试API接口是否正常呢
python中做接口测试工具一般都是用requests库
我们先在mydjango中创建一个应用API、再创建一个py文件
然后输入以下代码
import requests,pprint
#登录接口测试
pargd={'username':'sa','password':'663344abc..'} #先定义接口对应的字典、就是先看看提供的接口有哪些字段、然后输入登录帐户密码
postss=requests.post('http://127.0.0.1:8085/api/mgr/signin', #post(urls,data='')方法一定要正确的url、然后让data参数接收上面的登录信息
data=pargd) #signin这个是mgr.url里的路径
pprint.pprint(postss.json()) #这里打印不是用print、而是用pprint、最后请求的参数于json格式显式
#查询接口测试
pargd2={'action':'list_customer'}
getss=requests.get('http://127.0.0.1:8085/api/mgr/customers', #这个是get方法、get方法的参数是params接收
params=pargd2)
pprint.pprint(getss.json())
#退出接口测试
pargd3={'username':'sinout'}
postss=requests.post('http://127.0.0.1:8085/api/mgr/sinout',data=pargd3)
pprint.pprint(postss.json())
#添加接口测试
pargd4={'action':'add_customer','data':{'id':123,'name':8975,'phonenumer':564,'address':5646}}
postt=requests.post('http://127.0.0.1:8085/api/mgr/customers',json=pargd4)
pprint.pprint(postt.json())
#修改接口测试
pargd4={'action':'modify_customer','id':1,'newdata':{'name':8975,'phonenumer':564,'address':5646}}
postt=requests.post('http://127.0.0.1:8085/api/mgr/customers',json=pargd4)
pprint.pprint(postt.json())
#删除接口测试
pargd5={'action':'del_customer','id':3}
data1=requests.post('http://127.0.0.1:8085/api/mgr/customers',json=pargd5)
pprint.pprint(data1.json())
如果接口测试出现各种问题、请按问题来解决:
1、Pycharm运行测试用例报错:ConnectionRefusedError: [WinError 10061] 由于目标计算机积极拒绝,无法连接。
可能的报错原因及对应解决办法:
- Appium服务未启动。启动Appium服务即可。
- 局域网设置为配置为自动检测,如下图,配置好确认即可。
2、可能是URL地址写错、或者django服务器没启动
3、查看是不是代码写错了、尤其是KEY与VULUES值
4、查看一下登录代码signin这个函数里的是不是正确的、大小写也要认真看完
注意:当我们打开index.hmtl这个网址的时候可以直接绕过登录界面、这时我们就要去查询的API接口做个判断了。
我们处理 URL 以 /api/mgr
开头的 API 请求 代码里面, 需要 加上一个验证逻辑。
验证请求的cookie里面是否有sessionid,并且检查session表,看看是否存在session_key为该sessionid 的一条记录,该记录的数据字典里面是否 包含了 usertype 为 mgr 的 数据。
前面实现的代码中, 这些请求都是在dispatcher入口函数处理的,我们就只需在该dispatch中进行验证。
修改 mgr/customer.py
的dispatcher 函数,在前面加上如下代码
# 根据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对象里面的session属性对应的就是 session记录里面的 数据。
该数据对象类似字典,所以检查是否有usertype类型为mgr的信息,就是这样写
if request.session['usertype'] != 'mgr'
以下是代码:
import json
from django.http import JsonResponse
from common.models import Customer
import common.models
def dispatcher(request):
# #根据session判断用户是否是登录的管理员用户,如果是那就可以执行以下函数的添加、修改、删除等操作、普通用户就只有查看了
session1=request.session['usertype']='mgr' #把数据库的管理员赋值给session1、这样才能更好判断、现在session1就是管理员
if session1 not in request.session: #如果管理员不是数据库里的就报302
return JsonResponse({'ret':302,
'msg':'未登录',
'redirect':'/mgr/sign.html'},
status=302) #这个是http/1.1响应参数返回的是多少
if request.session['usertype']!='mgr': #判断session这个数据库里的类型是不是管理员、与上面的不同哦、上面是直接就是管理员
return JsonResponse({'ret':302,
'msg':'用户非mgr类型',
'redirect':'/mgr/sign.hmtl'},
status=302)
# 将请求参数统一放入request的params属性中,方便后续处理
# GET请求 参数在url中,同时request对象的GET属性获取
if request.method == 'GET':
request.params = request.GET
# POST/PUT/DELETE(添加、修改、删除、上面GET是查询)4种请求参数从request对象的body属性中获取
elif request.method in ['POST', 'PUT', 'DELETE']:
# 根据接品、POST/PUT/DETELE请求的消息体都是json格式
request.params = json.loads(request.body)
# 根据不同的action分派给不同的函数进行处理
action = request.params['action']
if action == 'list_customer': #如果{action:list_customer}就执行listcustomers函数
return listcustomers() # 列出客户函数、这个函数在下面创建
elif action == 'add_customer':
return addcustomers(request) # 添加客户函数
elif action == 'modify_customer':
return modifycustomer(request) # 修改客户函数
elif action == 'del_customer':
return deletecustomer(request) # 删除客户函数
else:
return JsonResponse({'ret': 1, 'msg': '不支持该类型的http请求'})
#查询API
def listcustomers():
# 返回一个 QuerySet 对象 ,包含所有的表记录
qs = common.models.Customer.objects.values() # 这个函数是从common这个APP里的models.py文件里的类属性、也可以用from\import先导入APP
# 然后把上面的类属性转化为list(列表)、否则不能在网页上转化为json字符串
retlist = list(qs)
return JsonResponse({'ret': 0, 'retlist': retlist}) # 返回给接口里的那2个字典元素、分别是ret、retlist(上面转化为listr的变量)
#添加API
def addcustomers(request):
info = request.params['data']
# 从请求消息中获取要添加客户的信息
# 并且插入到数据库中
# 返回值就是对应插入记录的对象
record = common.models.Customer.objects.create(name=info['name'], # 这个函数是从common这个APP里的models.py文件里的类属性\每个字段对应这个类里的变量
phonenumber=info['phonenumber'],
address=info['address']
)
return JsonResponse({'ret': 0, 'id': record.id}) # 返回给接口的那2个字典元素,分别是ret、id(因为ID是动态自增长的、又要返回上面的变量).点name就是name这个字段
#修改API
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})
#删除API
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})