大家好,这里是<测试开发实战-手把手系列之三>
这一节主要讲解每个文件的作用
先放一张上一节的结构图
model.py
主要是定义model,与数据库中保持一致,内容如下:
import ...
#id、name...与数据库中的字段一一对应
class productModel(models.Model): #一个class类
id = models.AutoField(primary_key=True) #AutoField:自增类型, primary_key:主键
name = models.CharField(max_length=64) #CharField:字符串类型 max_length:长度
description = models.CharField(max_length=255)
ftp_path = models.CharField(max_length=255)
creator_id = models.IntegerField(max_length=11)
create_time = models.DateTimeField(auto_now_add=True) #DateTimeField 时间类型,auto_now_add:新增时取当前时间
status =models.IntegerField(max_length=11)
close_id = models.IntegerField(max_length=11)
close_time = models.DateTimeField(auto_now=False) #DateTimeField 时间类型,auto_now:取当前时间
class Meta:
db_table = "product" #db_table:表名称
views.py
主要是处理请求的接口逻辑,主要是增、删、改、查、分页查这5个基本接口
内容如下:
#添加方法#
import ...
#添加
class InsertRecord(View): #一个class类,继承View
def post(self, request): #def:函数关键字,post方法
dto = json.loads(request.body) #获取请求的body
name = dto.get("name", "") #获取name的值,如果没有则赋值为""
description = dto.get("description", "")
ftp_path = dto.get("ftp_path", "")
creator_id = dto.get("creator_id", "")
status = dto.get("status", "")
Record = productModel(name=name, description=description, ftp_path=ftp_path, creator_id=creator_id,status=status) #新建productModel对象并赋值
Record.save() #保存至数据库
return HttpResponse(json.dumps({"code": 10000}), content_type="application/json") #返回JSON字符串格式的响应结果{"code": 10000}
逻辑:
获取请求数据,对象赋值,保存数据,返回json格式字符串
要点:
1、接口的请求方法,代码中规定了以post方法请求,view还支持get/head/options/delete/put/patch这些方法,具体用法为:
class InsertRecord(View):
def get(self,request):
#你的逻辑
return HttpResponse()
def post(self,request):
# 你的逻辑
return HttpResponse()
def delete(self,request):
#你的逻辑
return HttpResponse()
2、json.loads(request.body):获取请求body并转为字典(需要掌握什么是python的字典以及json.loads的用法)
3、新建productModel对象并赋值
4、django中model的save()方法插入数据库
5、json.dumps()方法返回json字符串
#删除方法#
#删除
class DeleteById(View):
def post(self, request):
dto = json.loads(request.body)
Record = productModel.objects.get(id=dto.get('id')) #通过id获取1条model对象数据
Record.delete() #从数据库中删除
return HttpResponse(json.dumps({"code":20000}),content_type="application/json")
逻辑:获取删除的数据,执行删除,返回结果
要点:
1、objects.get()方法获取1条对象数据
2、QuerySet:表示从数据库中获取的对象集合,也称查询结果集
3、django的delete()方法,数据库删除
#修改方法#
#根据id修改
class UpdateBySelective(View):
def post(self, request):
dto = json.loads(request.body)
id = dto.get('id')
Record = productModel.objects.get(id=id) #objects.get方法,通过获取id获取记录
if dto.get('name'): #前端是否修改name
Record.name = dto.get('name') #name更新为前端传入的要修改的值
if dto.get('create_time'):
Record.create_time = dto.get('productcreate_time')
if dto.get('status'):
Record.status = dto.get('status')
if Record.status == 2: #如果状态修改为关闭,记录关闭人和关闭时间
Record.close_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) #格式化当前时间:2019-04-15 14:23:21
elif Record.status == 1: #如果状态修改为开启,清空关闭人和关闭时间
Record.close_id = None
Record.close_time = None
Record.save() #更新数据库。save方法会先判断,id不存在时新增记录,存在时更新记录
return HttpResponse(json.dumps({"code":20000}),content_type="application/json")
逻辑:获取要修改的记录,重新赋值,更新数据,返回结果。
要点:要注意save()用法,django会判断是否存在有id来执行update或insert
#查询所有#
#查询所有
class SelectAll(View):
def post(self,request):
listRes = productModel.objects.values() #objects.values()方法返回包含字典dict的QuerySet数组
listRes = list(listRes) #转化为list类型的字典dict,python的7大数据类型之一
return HttpResponse(json.dumps({"modelList": listRes, "code": 10000},cls=DjangoJSONEncoder),content_type="application/json") #返回JSON字符串格式的响应结果
逻辑:查询结果集,返回结果。
要点:
1、objects.values()返回指定字段的dict列表;objects.all()返回对象列表;
2、list()方法强制转成list类型,这里需要掌握python的7大数据类型
#根据条件查询#
#根据条件查询
class SelectBySelective(View):
def post(self,request):
dto = json.loads(request.body)
recordList = productModel.objects.all() #objects.all()方法返回QuerySet对象列表
if dto.get('id'):
recordList = recordList.filter(id=dto.get('id')) #filter()方法过滤查询结果
if dto.get('create_time'):
recordList = recordList.filter(create_time=dto.get('create_time'))
if dto.get('status'):
recordList = recordList.filter(status=dto.get('status'))
listRes = []
for item in recordList:
json_dict = model_to_dict(item) #model_to_dict()方法将QuerySet对象转换成字典对象
listRes.append(json_dict)
return HttpResponse(json.dumps({"modelList":listRes,"code":20000},cls=DjangoJSONEncoder),content_type="application/json")
逻辑:获取查询数据,根据数据过滤结果,返回结果
要点:
1、objects.all()返回的是对象列表,objects.values()返回的是dict列表
2、django的filter()方法,对结果进行过滤
#分页查询#
#分页查询
class SelectByPage(View):
def post(self,request):
dto = json.loads(request.body)
limit = int(dto.get('rows')) #获取前端每页显示的条数 int()方法:强制转换为int型
offset = (int(dto.get('page')) - 1)*limit #获取当前页码
sort = dto.get('sort') #获取排序字段
order = dto.get('order')#获取排序规则:正序或倒序
targets = productModel.objects.all()
if dto.get('status'):
status = dto.get('status')
targets = productModel.objects.values().filter(status=status)
if dto.get('search'):
search = dto.get('search')
targets = productModel.objects.values().filter(Q(name__icontains=search) | Q(description__icontains=search))#根据name和description进行模糊查询:Q()方法和icontains关键字
length = len(targets) # len()方法:获取列表的长度
if not limit:
targets = productModel.objects.values()
if sort:
sort = sort if order == 'asc' else '-' + sort
targets = targets.order_by(sort) #order_by():排序
else:
offset = int(offset)
limit = int(limit)
if sort:
sort = sort if order == 'asc' else '-' + sort
targets = targets.order_by(sort)[offset:offset + limit]
else:
targets = targets[offset:offset + limit]
data_set= []
for item in targets :
json_dict = model_to_dict(item)
data_set.append(json_dict)
return HttpResponse(json.dumps({"rows":data_set,"total":length,"code":20000},cls=DjangoJSONEncoder), content_type='application/json')
逻辑:获取分页请求参数,返回结果
要点:
1、objects.all()返回的是对象列表,objects.values()返回的是dict列表
2、django的filter()方法,对结果进行过滤
3、这里要说明讲下Q()方法和icontains关键字
Q是个组合操作符,类似这样:(Q(条件) | Q(条件)),等同于sql:where or;
icontains的意思是:忽略大小写
(具体使用方法看官网)
以上就是基本的view接口逻辑。
urls.py
应用接口的访问设置
from django.urls import path
from product import views
urlpatterns = [
path('InsertRecord', views.InsertRecord.as_view()),
# path('DeleteById', views.DeleteById.as_view()), #不允许物理删除,所以去掉此方法
path('UpdateBySelective', views.UpdateBySelective.as_view()),
path('SelectAll', views.SelectAll.as_view()),
path('SelectBySelective', views.SelectBySelective.as_view()),
path('SelectByPage', views.SelectByPage.as_view()),
]
逻辑:设置对外访问的接口
要点:path()方法:path(接口名称,类)
然后就是在myproject下的setting.py中加入应用
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘product’ # 添加此项
]
最后在myproject下的urls.py中设置应用的对外接口
from django.urls import path,include
urlpatterns = [
path(‘product/’, include(‘product.urls’)),# 添加此项
]
以上,一个应用的接口就开发完成了.我们启动django(启动方法上一节介绍过),然后使用postman测试一下product的SelectAll接口
结果报错,提示
Forbidden (CSRF token missing or incorrect.)
这个是因为django做了CSRF校验,我们先在setting.py中注释掉中间件。
MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
‘django.middleware.common.CommonMiddleware’,
#‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]
再测一下接口
可以看到接口返回正常
**
总结
**
本章主要介绍django编写基本结构的代码
1、定义model,与数据库进行映射
2、基础view接口方法:新增、修改、查询所有、根据条件查询、分页查询
3、定义对外接口名称
后面我们创建的任何应用(APP)都会按照这个基础模式先码一遍。如果有其他的接口逻辑,再添加即可。
演示代码:
https://github.com/danzi516/TestDev/tree/main/%E6%89%8B%E6%8A%8A%E6%89%8B/3/myproject
更多文章,关注一波,谢!