- django 前期工作
- HTTP请求路由
- 路由子表
- 创建数据库和表
- 管理员admin
- 读取数据库中数据
- 过滤条件
- 前后端分离
- 对资源的增删改查
- 总结
django 前期工作
安装
pip install django
查看是否安装成功
python -m django --version
创建Django项目命令
django-admin startproject wtsms
项目中默认生成的文件
setting:配置项目
urls:路由文件,请求,控制返回的请求谁来处理
wsgi:server/application,配置,application 调用函数,方法,
那server怎么去调用application中的django,处理http请求的代码,通过这个文件,wsgi.py
manage:工具性脚本
进入项目(根目录:D:pythonProjects/wtsms),输入命令,启动
python manage.py runserver 0.0.0.0:80
设置其他ip可以访问:
settings------->ALLOWED_HOST=[‘ip地址’] #允许访问
HTTP请求路由
案例,开发,实现公司的销售管理系统
一个http请求过来了,怎么样跑到代码里来处理请求
创建项目app------->指的是Django里的
app—>独立,完整模块,功能
功能划分: 管理员、销售员
app---->就是一个python包,存储了功能实现的所有代码
创建app,也会有一些内置配置文件(相同的)
使用Django来帮我们实现,自动生成
进入项目根目录,执行命令
python manage.py startapp sals
里生成的文件后面会讲,认真看完哦。
当浏览器中,有个客户端的http请求过来了,怎么根据请求返回给浏览器页面内容呢?
服务器返回的是字符串,那怎么让django返回字符串呢?
views.py,一般处理请求返回数据,views.py 定义一个函数,urls.py
url的入口文件,所有发送过来的url请求都会先到这,,控制返回的请求给谁,指向了listorders。
路由子表
先找第一级别urls.py里面包含的路径
比如说:包含
销售:sals/ordlers1,sals/orders2,sals/orders3。。。
管理员:admin/xxx1,admin/xxx2,admin/xxx3。。。
首先找主表下的urls.py
查找包含sals/路径开头的,他就会去子表sals中的urls查找
只需要写他剩余的路径和打开这个路径需要调用那个方法,二级路由表需要把一级已经匹配上的路由表去掉
找到方法,调用sals.view 中对应的方法
表太大了,可以一层一层的拆分
注意:path 中的指定路径可以是一个复杂的正则表达式
创建数据库和表
之前只是给我们浏览器返回了一句话,并不是真实的订单信息
后端开发--------操作数据(增删改查)
当前使用sqlite,django自带,
数据库配置:wtsys/settings .py 文件
如果没有的话,输个命令:
python manage.py migrate,执行在根目录下生成db.sqlite3文件,还会生成一些配置文件。默认的那个db.sqlite3,是为空的。
生成一些表
ORM 将数据库里面,映射成对象和对象之间的关系
定义数据库表
创建一个公共的应用,共同需要访问的数据表----comon
python manage.py startapp comon
定义数据库表,通常是在models.py 里面
考虑问题,那怎么让Django 知道我创建了这么一张表?
首先,在settigng 中添加我新建的app----->comon
apps.py指定应用的名字,eg:comon,指明该app的名字,到时候直接来找
命令行输入:
在comon 下的migrations 生成了0001——intitial.py
这一步,只是产生相应变动的代码文件
如果需要真正提交到数据库中,还需要执行:python manage.py migrate,重新生成sqlite3.py 文件,提交创建的表到数据库
发现数据库sqlite3中多了一张表
如果数据库增加了字段等情况,比如增加qq,这个字段
又需要重新执行python manage.py makemigrations comon,发现问题,如果以前已经有了数据,没有qq这个字段,让他选择可以允许为空,不做任何修改
接着:python manage.py migrate,查看s qlite3 刷新,添加成功
管理员admin
一开始没有任何数据,如何添加管理员用户呢
输入命令
python manage.py createsuperuser
需要输入用户名
邮箱
密码
确认密码,最后查看,sqlite3中进行查看
Django 内置了一个专门给管理员登录的界面,启动服务,python manage.py runserver 0.0.0.0:80
登录网址:http://localhost/admin/,输入刚刚填写的用户名和密码
发现没有刚刚创建的表,公共表,不能对其进行操作
修改配置,让django知道
comon------->admin.py文件下,添加内容
from .models import Customer
admin.site.register(Customer)
添加name,phonenumber,address,qq,刷新sqlite3 出现刚刚创建的数据
一般情况这只是给开发者或者管理员使用的,不会让用户直接使用。。。
读取数据库中数据
前端发送请求,需要从数据库把需要用到的数据获取出来,返回给浏览器
一个如果需要通过对数据库进行操作,通常是Customer.objects
from comon.models import Customer
def listcustomers(request):
#拿到所有数据库中的值,返回一组对象QuerySet()
qs = Customer.objects.values()
#遍历数据
resStr=''
for customer in qs:
for name,values in customer.items():
resStr='f{name} : {values} |'
resStr+='<br>'
#返回请求给浏览器
return HttpResponse(resStr)
配置url的路径:sals/customers2
父级配好了:sals,include(‘sals.urls’)
子级配置:/customers2,views中的定义的方法listcustomers
访问:http://localhost/sals/cumstomers2
根据url路由,就会返回到调用那个函数,返回给浏览器,遍历数据库中的数据
过滤条件
我们查询的时候,肯定有时候会带一些条件的,而并不是查询所有的数据库数据
后端处理呢,是把url中需要查询的条件拿出来,然后再去数据库中查询----------listcustomers中写入
#查看request 中是否存在phonenumber 这个字符串,如果没有存在这个字符串,返回一个none
phone=request.GET.get('phonenumber',None)
#如果条件为真,存在
if phone:
#添加过滤条件,需要的是这个手机号的数据
ph=ph.filter(phonenumber=phone)
GET:把我们需要请求的所有数据以一个字典的形式呈现
{
‘phonenumber’:‘123456789’,
‘qq’:‘54233212’
}
前后端分离
之前获取到的数据,非常的丑,虽然也能拿到数据
那怎么可以变得更加好看呢?用html来存放数据
返回的字符串,符合html语法
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from comon.models import Customer
def listorders1(request):
return HttpResponse("下面是系统中所有的订单信息111。。。")
#request 会携带http请求过来的一些数据
# 先定义好HTML模板
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>
<th>qq</th>
</tr>
%s
</table>
</body>
</html>
'''
htmlResponse=".....html所有的内容"
def listcustomers(request):
#获取所有数据
rq = Customers.objects.values()
#过滤,GET,phonenumber
ph = request.GET.get('phonenumber',None)
#filter 过滤
if ph:
rq = rq.filter(phonenumber=ph)
#定义变量存放数据
tablelist=''
#遍历满足条件测数据
for customer in rq:
#使用tr控制一行数据
tablelist+='<tr>'
#遍历具体的name,value,这里只需要value
for name,value in customer.items():
tablelist+=f'<td>{value}</td>'
#</tr>结束标签
tablelist+='</tr>
#返回给浏览器,html页面和具体的数据 html,%s 使用%tableContent进行替换
return HttpResponse(htmlResponse%tablelist)
显示效果:
但发现一个问题,如果是需要很多动态的数据,就会显得非常麻烦
这样我们就可以使用模板,直接在html中嵌入我们的python代码
但是后端还是需要做很多前端工作。
真正的前后端分离,让后端人员从前期脱离出来,如果前端页面不断的调整,后端也要不断的返工,非常的麻烦。
后端,现在只负责传数据,页面的展示直接交给前端来做
前端通过api请求接口,从后端获取数据展示到界面上
前端通过api接口,告诉后端我需要更新的数据是什么,后端调用数据库,直接进行更新
之后返回的信息,完全就是数据信息了,而不是返回html的信息了
只要返回数据(json 格式)就可以了,前端怎么展示这些数据,后端不需要管
那么后端人员,怎么根据api接口返回对应的数据
对资源的增删改查
对数据的管理,前端有请求过来,对资源的增加,修改,列出删除,响应他的请求
创建一个以管理员用户创建一个用户
之前已经建好了,销售员sals 的app
执行命令:
python manage.py startapp mgroot
之前我们的所有操作都是在views.py文件进行操作的
如果将所有请求都放在views.py文件中处理,会显得很大
所有进行拆分
eg:将管理员的客户端的操作,增删改查进行操作,存放在一个文件下,customer.py
而将对订单的所有操作,存放在另一个文件下,order.py,易于管理
Django不支持以请求的方法(get,put,delete.post)来判断它具体是哪种请求
也不支持看请求体里有哪些参数,进行路由
父级路由编写:urls.py
path('/api/mgroot/',include('mgroot.urls')),
子级路由编写
from mgroot import customer
path('customers',customer.dispatcher)
定义customer 中的方法
def dispatcher(request):
#判断请求方法
if request.method=="GET":
#使用params存储,获取url中的所有信息,存放,方便以后读取
request.params = request.GET
#如果不是GET请求呢,根据接口文档,内容存放在消息体里面,那如何能读到json中的请求信息呢?
#因为只有读到里面的信息才能判断出是哪种格式
elif request in ['POST','PUT','DELETE']:
request.params=json.loads(request.body)
#根据不同的action 分为不同的函数
知道了是哪种请求类型,再根据action 获取到request.method 中的action,再根据不同的action 分配给不同的函数进行相应的处理。
#获取已经存储好的action的数据
action=request.params['action']
#判断具体的数据的值
if action == 'list_customer':
#返回对应函数,做相应的处理
return listcustomers(request)
elif action =='add_customer':
return addcustomers(request)
elif action =='modify_customer':
return modifycustomers(request)
elif action =='del_customer':
ruturn delcustomers(request)
else:
return JsonResponse({'ret':1,'msg':'不支持该请求,有错误'})
如何返回像接口文档那种json 格式的数据字典给浏览器呢
将数据库中的数据读出来。存放在json 的这一一个列表中
1.调用返回所有列表 中数据的方法
#首先需要拿到数据库中的数据
from comon.models import Customer
def listcustomers(request):
#定义一个变量接收所有的数据
re_list = Customer.object.values()
#转化格式
ret_list=list(re_list)
#返回数据
return JsonReponsed({'ret':'0','retlist':ret_list})
2.添加用户,无非就是获取data 中的数据
def addcustoms(request):
#获取data中所有数据
re_list=request.params['data']
#获取数据中需要的数据
recond = Customer.object.create(
name=re_list['name'],
phonenumber=re_list['phonenumber'],
address=re_list['address']
)
#需要返回的数据
return JsonResponse('ret':0,'id':recond)
临时取消CSRF校验
当客户端发过来的请求还没到调用方法时,只是经过Django框架,会对它做一个校验,也是为了防止CSRF的攻击
在开发的时候可以注释掉,项目文件下的setting.py文件中的注释这行代码,先取消验证,到时候再开
3.修改用户信息
获取数据,和对应的id值,和数据库中的数据进行校验,
def modifycostumer(request):
#获取传过来的数据
info_costumer = request.params['newdate']
#获取id值
info_id =request.params['id']
#id是否存在
try:
#会去数据库中找,如果找到了,返回一个变量,代表的是一条记录
customer = Customer.objects.get(id=info_id)
except Customer.DoesNotExist:
return {
'ret':1,
'msg':f'id为`{info_id}`的客户不存在'
}
#数据的替换,覆盖
if 'name' in info_costumer:
#把旧的名字替换成传过来数据中的name
customer.name=info_costumer['name']
#电话phonenumber
if 'phonenumber' in info_params:
customer.phonenumber = info_params['phonenumber']
#地址address
if 'address' in info_params:
customer.address = info_params['address']
#保存数据,存到数据库中去
customer.save()
#返回成功数据
return JsonResponse({'ret':0})
4.删除数据
def deletecustomer(request):
#获取数据id
id_customer = request.params['id']
#判断id 是否存在
try:
customer=Customer.object.get(id=id_customer)
except Cumsomer.DoesNotExist:
return {
'ret':1,
'msg':'id为f`{id_customer}`的客户不存在'
}
#存在,删除
customer.delete()
#返回
return JsonResponse({'ret':0})
。。。管理员对客户的操作已经完成。
接口已经开发好了,那如何测试代码
模拟前端,发出http请求,对后端进行测试
那开发完成了,如何进行测试呢,当前端还没有开发完成的时候
我们可以构建http请求,看服务器给我们返回什么信息,来查看有没有bug
经常使用的一个库:requests这个库
常用到软件测试中的接口自动化测试中
实例:
import requests,pprint
payload={
'username':'wwt',
'password':'88888888'
}
response=requests.post("http://localhost/api/mgr/signin",data=payload)
pprint.prrint(response.json())
这样我们就可以通过看返回的数据,是不是自己定义的数据就可以达到测试的效果了,并不需要等待前端开发完了再进行测试。
总结
呃呃,做个总结吧,通过上面的代码,也带大家了解了一下django,前期的部署,内部的表,参数,如何运转的,如何过滤掉不想要的数据,拿到前端需要拿到的数据,后端的工作无非是将数据传给前端了,前端拿到数据,要对它进行怎样的展示,我们都不用操心的,那么,建表的任务可谓是重中之重了,如何灵活的的运用表之间的关联,比如说吧,定义了一张学生表(包含班级),和一张国家表,如何如何拿到班级为1,国家都是美国的表数据呢?表与表之前存在非常多的联系,还有事务的使用。后期,带大家深入了解,关注我,不迷路哦。。。