启动前端服务:
npm run build
启动后台服务:
python manage.py runserver 0.0.0.0:8888
1.安装virtualenvwrapper-win
2.new django project
3.pip install django
4.pip install mysqlclient==1.4.6
5.settings.py 里面配置数据库连接信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'HOST': '127.0.0.1', # 数据库主机
'PORT': 3306, # 数据库端口
'USER': 'root', # 数据库用户名
'PASSWORD': '123456', # 数据库用户密码
'NAME': 'test' # 数据库名字
}
}
6.pip install djangorestframework
7.settings.py文件中配置rest_framework
8.new utils 文件夹
9.在utils下new custom_response_middler_ware.py
10.自定义响应中间件
class ResponseMiddleware:
def __init__(self, get_response):
self.get_response = get_response
# 配置和初始化
def __call__(self, request):
# 在这里编写视图和后面的中间件被调用之前需要执行的代码
# 这里其实就是旧的process_request()方法的代码
response = self.get_response(request)
# if "code" not in response.data:
#
# data = response.data
# response.data={
# "code":"0000",
# "message":"查询成功",
# "data":response.data
# }
# # 因返回时已经render过response,要想让这里的修改有效,需要手动在render一次
# response._is_rendered = False
# response.render()
# response["content-length"]=len(response.content)
# 在这里编写视图调用后需要执行的代码
# 这里其实就是旧的 process_response()方法的代码
return response
def process_template_response(self, request, response):# 推荐
if "code" not in response.data:
data = response.data
response.data={
"code":"0000",
"message":"操作成功",
"data":response.data
}
# 在这里编写视图调用后需要执行的代码
# 这里其实就是旧的 process_response()方法的代码
return response
11.settings>MIDDLEWARE 配置响应中间件(响应中间件放最上面,请求中间件放最下面)
![](https://img.haomeiwen.com/i12041469/d47a572c5ce04cb3.png)
- 自定义响应异常类
from rest_framework import status
from rest_framework.exceptions import ValidationError
from rest_framework.views import exception_handler as drf_exception_handler
from utils.custome_response import CustomeResponse
def exception_handler(exc,context):
"""
自定义异常处理
:param exc: 别的地方抛的异常就会传给exc
:param context: 字典形式。抛出异常的上下文(即抛出异常的出处;即抛出异常的视图)
:return: Response响应对象
"""
response = drf_exception_handler(exc,context)
if response is None:
# drf 处理不了的异常
print('%s - %s - %s' % (context['view'], context['request'].method, exc))
return CustomeResponse({'detail': '服务器错误'}, code=500,msg="服务器内部错误",status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
if isinstance(exc,ValidationError):
message = ""
data = response.data
for key in data:
message += ";".join(data[key])
return CustomeResponse(None,code="9999",msg=message)
return response
REST_FRAMEWORK = {
....
# 自定义异常函数
'EXCEPTION_HANDLER':'utils.custome_exception.exception_handler',
....
}
13.自定义Response类
from rest_framework.response import Response
class CustomeResponse(Response):
def __init__(self,*args,code='0000',msg="成功",**kwargs):
# 格式化data
data = {
"code":code,
"message":msg
}
if args is not None:
data["data"]=args[0]
kwargs["data"] = data
elif "data" in kwargs:
data["data"] = kwargs["data"]
kwargs["data"]=data
super().__init__(**kwargs)
14.创建app
python manage.py startapp guoya_api
15.settings>INSTALLED_APPS里面配置app
16.配置路由,分发信息
主路由配置子路由
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('v01/', include('guoya_api.urls')),
]
17.app>models.py定义模型
from django.contrib.auth.models import User
from django.db import models
# Create your models here.
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
HTTP_CHOICE = (
('HTTP', 'HTTP'),
('HTTPS', 'HTTPS')
)
REQUEST_TYPE_CHOICE = (
('POST', 'POST'),
('GET', 'GET'),
('PUT', 'PUT'),
('DELETE', 'DELETE')
)
REQUEST_PARAMETER_TYPE_CHOICE = (
('form-data', '表单(form-data)'),
('raw', '源数据(raw)'),
('Restful', 'Restful')
)
PARAMETER_TYPE_CHOICE = (
('text', 'text'),
('file', 'file')
)
HTTP_CODE_CHOICE = (
('200', '200'),
('404', '404'),
('400', '400'),
('502', '502'),
('500', '500'),
('302', '302'),
)
EXAMINE_TYPE_CHOICE = (
('no_check', '不校验'),
('only_check_status', '校验http状态'),
('json', 'JSON校验'),
('entirely_check', '完全校验'),
('Regular_check', '正则校验'),
)
UNIT_CHOICE = (
('m', '分'),
('h', '时'),
('d', '天'),
('w', '周'),
)
RESULT_CHOICE = (
('PASS', '成功'),
('FAIL', '失败'),
)
TASK_CHOICE = (
('circulation', '循环'),
('timing', '定时'),
)
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
# ==================扩展用户====================================
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='用户', related_name='user')
phone = models.CharField(max_length=11, default='无', blank=True, verbose_name='手机号')
openId = models.CharField(max_length=50, default=0, verbose_name="唯一标识")
unionid = models.CharField(max_length=50, default=0, verbose_name="企业内唯一标识")
def __unicode__(self):
return self.user.username
def __str__(self):
return self.phone
class Project(models.Model):
"""
项目表
"""
ProjectType = (
('Web', 'Web'),
('App', 'App')
)
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, verbose_name='项目名称')
version = models.CharField(max_length=50, verbose_name='版本')
type = models.CharField(max_length=50, verbose_name='类型', choices=ProjectType)
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
status = models.BooleanField(default=True, verbose_name='状态')
LastUpdateTime = models.DateTimeField(auto_now=True, verbose_name='最近修改时间')
createTime = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, max_length=1024, verbose_name='创建人')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '项目'
verbose_name_plural = '项目'
class ProjectDynamic(models.Model):
"""
项目动态
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, related_name='dynamic_project', on_delete=models.CASCADE, verbose_name='所属项目')
time = models.DateTimeField(max_length=128, verbose_name='操作时间')
type = models.CharField(max_length=50, verbose_name='操作类型')
operationObject = models.CharField(max_length=50, verbose_name='操作对象')
user = models.ForeignKey(User, blank=True, null=True, related_name='userName',
on_delete=models.SET_NULL, verbose_name='操作人')
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
def __unicode__(self):
return self.type
class Meta:
verbose_name = '项目动态'
verbose_name_plural = '项目动态'
class ProjectMember(models.Model):
"""
项目成员
"""
CHOICES = (
('超级管理员', '超级管理员'),
('开发人员', '开发人员'),
('测试人员', '测试人员')
)
id = models.AutoField(primary_key=True)
permissionType = models.CharField(max_length=50, verbose_name='权限角色', choices=CHOICES)
project = models.ForeignKey(Project, related_name='member_project', on_delete=models.CASCADE, verbose_name='所属项目')
user = models.ForeignKey(User, related_name='member_user', on_delete=models.CASCADE, verbose_name='用户')
def __unicode__(self):
return self.permissionType
def __str__(self):
return self.permissionType
class Meta:
verbose_name = '项目成员'
verbose_name_plural = '项目成员'
class GlobalHost(models.Model):
"""
host域名
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
name = models.CharField(max_length=50, verbose_name='名称')
host = models.CharField(max_length=1024, verbose_name='Host地址')
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
status = models.BooleanField(default=True, verbose_name='状态')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = 'HOST'
verbose_name_plural = 'HOST管理'
class CustomMethod(models.Model):
"""
自定义方法
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
name = models.CharField(max_length=50, verbose_name='方法名')
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
type = models.CharField(max_length=50, verbose_name='类型')
dataCode = models.TextField(verbose_name='代码')
status = models.BooleanField(default=True, verbose_name='状态')
def __unicode__(self):
return self.name
class Meta:
verbose_name = '自定义方法'
verbose_name_plural = '自定义方法'
class ApiGroupLevelFirst(models.Model):
"""
接口一级分组
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
name = models.CharField(max_length=50, verbose_name='接口一级分组名称')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '接口分组'
verbose_name_plural = '接口分组'
class ApiInfo(models.Model):
"""
接口信息
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, related_name='api_project', on_delete=models.CASCADE, verbose_name='所属项目')
apiGroupLevelFirst = models.ForeignKey(ApiGroupLevelFirst, blank=True, null=True,
related_name='First',
on_delete=models.SET_NULL, verbose_name='所属一级分组')
name = models.CharField(max_length=50, verbose_name='接口名称')
httpType = models.CharField(max_length=50, default='HTTP', verbose_name='http/https', choices=HTTP_CHOICE)
requestType = models.CharField(max_length=50, verbose_name='请求方式', choices=REQUEST_TYPE_CHOICE)
apiAddress = models.CharField(max_length=1024, verbose_name='接口地址')
requestParameterType = models.CharField(max_length=50, verbose_name='请求参数格式', choices=REQUEST_PARAMETER_TYPE_CHOICE)
status = models.BooleanField(default=True, verbose_name='状态')
mockStatus = models.BooleanField(default=False, verbose_name="mock状态")
mockCode = models.CharField(max_length=50, blank=True, null=True, verbose_name='HTTP状态', choices=HTTP_CODE_CHOICE)
data = models.TextField(blank=True, null=True, verbose_name='mock内容')
lastUpdateTime = models.DateTimeField(auto_now=True, verbose_name='最近更新')
userUpdate = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, max_length=50, verbose_name='更新人',
related_name='ApiUpdateUser')
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '接口'
verbose_name_plural = '接口管理'
class ApiHead(models.Model):
id = models.AutoField(primary_key=True)
api = models.ForeignKey(ApiInfo, on_delete=models.CASCADE, verbose_name="所属接口", related_name='headers')
name = models.CharField(max_length=1024, verbose_name="标签")
value = models.CharField(max_length=1024, blank=True, null=True, verbose_name='内容')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '请求头'
verbose_name_plural = '请求头管理'
class ApiParameter(models.Model):
id = models.AutoField(primary_key=True)
api = models.ForeignKey(ApiInfo, on_delete=models.CASCADE, verbose_name="所属接口", related_name='requestParameter')
name = models.CharField(max_length=1024, verbose_name="参数名")
_type = models.CharField(default="String", max_length=1024, verbose_name='参数类型', choices=(('Int', 'Int'), ('String', 'String')))
value = models.CharField(max_length=1024, blank=True, null=True, verbose_name='参数值')
required = models.BooleanField(default=True, verbose_name="是否必填")
restrict = models.CharField(max_length=1024, blank=True, null=True, verbose_name="输入限制")
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name="描述")
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '请求参数'
verbose_name_plural = '请求参数管理'
class ApiParameterRaw(models.Model):
id = models.AutoField(primary_key=True)
api = models.OneToOneField(ApiInfo, on_delete=models.CASCADE, verbose_name="所属接口", related_name='requestParameterRaw')
data = models.TextField(blank=True, null=True, verbose_name='内容')
class Meta:
verbose_name = '请求参数Raw'
class ApiResponse(models.Model):
id = models.AutoField(primary_key=True)
api = models.ForeignKey(ApiInfo, on_delete=models.CASCADE, verbose_name="所属接口", related_name='response')
name = models.CharField(max_length=1024, verbose_name="参数名")
_type = models.CharField(default="String", max_length=1024, verbose_name='参数类型', choices=(('Int', 'Int'), ('String', 'String')))
value = models.CharField(max_length=1024, blank=True, null=True, verbose_name='参数值')
required = models.BooleanField(default=True, verbose_name="是否必含")
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name="描述")
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '返回参数'
verbose_name_plural = '返回参数管理'
class APIRequestHistory(models.Model):
"""
接口请求历史
"""
id = models.AutoField(primary_key=True)
api = models.ForeignKey(ApiInfo, on_delete=models.CASCADE, verbose_name='接口')
requestTime = models.DateTimeField(auto_now_add=True, verbose_name='请求时间')
requestType = models.CharField(max_length=50, verbose_name='请求方法')
requestAddress = models.CharField(max_length=1024, verbose_name='请求地址')
httpCode = models.CharField(max_length=50, verbose_name='HTTP状态')
def __unicode__(self):
return self.requestAddress
class Meta:
verbose_name = '接口请求历史'
verbose_name_plural = '接口请求历史'
class ApiOperationHistory(models.Model):
"""
API操作历史
"""
id = models.AutoField(primary_key=True)
api = models.ForeignKey(ApiInfo, on_delete=models.CASCADE, verbose_name='接口')
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, max_length=50, verbose_name='用户姓名')
time = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='操作内容')
def __unicode__(self):
return self.description
class Meta:
verbose_name = '接口操作历史'
verbose_name_plural = '接口操作历史'
class AutomationGroupLevelFirst(models.Model):
"""
自动化用例一级分组
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
name = models.CharField(max_length=50, verbose_name='用例一级分组')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '用例分组'
verbose_name_plural = '用例分组管理'
class AutomationTestCase(models.Model):
"""
自动化测试用例
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='所属项目')
automationGroupLevelFirst = models.ForeignKey(AutomationGroupLevelFirst, blank=True, null=True,
on_delete=models.SET_NULL, verbose_name='所属用例一级分组', related_name="automationGroup")
# automationGroupLevelSecond = models.ForeignKey(AutomationGroupLevelSecond, blank=True, null=True,
# on_delete=models.SET_NULL, verbose_name='所属用例二级分组')
caseName = models.CharField(max_length=50, verbose_name='用例名称')
user = models.ForeignKey(User, on_delete=models.SET_NULL, blank=True, null=True, verbose_name="创建人",
related_name="createUser")
description = models.CharField(max_length=1024, blank=True, null=True, verbose_name='描述')
updateTime = models.DateTimeField(auto_now=True, verbose_name='更新时间')
def __unicode__(self):
return self.caseName
def __str__(self):
return self.caseName
class Meta:
verbose_name = '自动化测试用例'
verbose_name_plural = '自动化测试用例'
class AutomationCaseApi(models.Model):
"""
用例执行接口
"""
id = models.AutoField(primary_key=True)
automationTestCase = models.ForeignKey(AutomationTestCase, on_delete=models.CASCADE,
verbose_name='用例', related_name="api")
name = models.CharField(max_length=50, verbose_name='接口名称')
httpType = models.CharField(max_length=50, default='HTTP', verbose_name='HTTP/HTTPS', choices=HTTP_CHOICE)
requestType = models.CharField(max_length=50, verbose_name='请求方式', choices=REQUEST_TYPE_CHOICE)
apiAddress = models.CharField(max_length=1024, verbose_name='接口地址')
requestParameterType = models.CharField(max_length=50, verbose_name='参数请求格式', choices=REQUEST_PARAMETER_TYPE_CHOICE)
formatRaw = models.BooleanField(default=False, verbose_name="是否转换成源数据")
examineType = models.CharField(default='no_check', max_length=50, verbose_name='校验方式', choices=EXAMINE_TYPE_CHOICE)
httpCode = models.CharField(max_length=50, blank=True, null=True, verbose_name='HTTP状态', choices=HTTP_CODE_CHOICE)
responseData = models.TextField(blank=True, null=True, verbose_name='返回内容')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '用例接口'
verbose_name_plural = '用例接口管理'
class AutomationHead(models.Model):
"""
请求头
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.ForeignKey(AutomationCaseApi, related_name='header',
on_delete=models.CASCADE, verbose_name='接口')
name = models.CharField(max_length=1024, verbose_name='参数名')
value = models.CharField(max_length=1024, verbose_name='内容')
interrelate = models.BooleanField(default=False, verbose_name='是否关联')
def __unicode__(self):
return self.value
class Meta:
verbose_name = '请求头'
verbose_name_plural = '请求头管理'
class AutomationParameter(models.Model):
"""
请求的参数
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.ForeignKey(AutomationCaseApi, related_name='parameterList',
on_delete=models.CASCADE, verbose_name='接口')
name = models.CharField(max_length=1024, verbose_name='参数名')
value = models.CharField(max_length=1024, verbose_name='内容', blank=True, null=True)
interrelate = models.BooleanField(default=False, verbose_name='是否关联')
def __unicode__(self):
return self.value
class Meta:
verbose_name = '接口参数'
verbose_name_plural = '接口参数管理'
class AutomationParameterRaw(models.Model):
"""
请求的源数据参数
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.OneToOneField(AutomationCaseApi, related_name='parameterRaw',
on_delete=models.CASCADE, verbose_name='接口')
data = models.TextField(verbose_name='源数据请求参数', blank=True, null=True)
class Meta:
verbose_name = '源数据参数'
verbose_name_plural = '源数据参数管理'
class AutomationResponseJson(models.Model):
"""
返回JSON参数
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.ForeignKey(AutomationCaseApi, related_name='response',
on_delete=models.CASCADE, verbose_name='接口')
name = models.CharField(max_length=1024, verbose_name='JSON参数', blank=True, null=True)
tier = models.CharField(max_length=1024, verbose_name='层级关系', blank=True, null=True)
type = models.CharField(max_length=1024, verbose_name="关联类型", default="json", choices=(('json', 'json'),('Regular', 'Regular')))
def __str__(self):
return self.name
class Meta:
verbose_name = '结果JSON参数'
verbose_name_plural = '结果JSON参数管理'
class AutomationTestResult(models.Model):
"""
手动执行结果
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.OneToOneField(AutomationCaseApi, on_delete=models.CASCADE, verbose_name='接口'
, related_name="test_result")
url = models.CharField(max_length=1024, verbose_name='请求地址')
requestType = models.CharField(max_length=1024, verbose_name='请求方式', choices=REQUEST_TYPE_CHOICE)
host = models.CharField(max_length=1024, verbose_name='测试地址', null=True, blank=True)
header = models.CharField(max_length=1024, blank=True, null=True, verbose_name='请求头')
parameter = models.TextField(blank=True, null=True, verbose_name='请求参数')
statusCode = models.CharField(blank=True, null=True, max_length=1024, verbose_name='期望HTTP状态', choices=HTTP_CODE_CHOICE)
examineType = models.CharField(max_length=1024, verbose_name='匹配规则')
data = models.TextField(blank=True, null=True, verbose_name='规则内容')
result = models.CharField(max_length=50, verbose_name='测试结果', choices=RESULT_CHOICE)
httpStatus = models.CharField(max_length=50, blank=True, null=True, verbose_name='http状态', choices=HTTP_CODE_CHOICE)
responseData = models.TextField(blank=True, null=True, verbose_name='实际返回内容')
testTime = models.DateTimeField(auto_now_add=True, verbose_name='测试时间')
def __unicode__(self):
return self.httpStatus
class Meta:
verbose_name = '手动测试结果'
verbose_name_plural = '手动测试结果管理'
class AutomationTestTask(models.Model):
"""
用例定时任务
"""
id = models.AutoField(primary_key=True)
project = models.OneToOneField(Project, on_delete=models.CASCADE, verbose_name='项目')
Host = models.ForeignKey(GlobalHost, on_delete=models.CASCADE, verbose_name='HOST')
name = models.CharField(max_length=50, verbose_name='任务名称')
type = models.CharField(max_length=50, verbose_name='类型', choices=TASK_CHOICE)
frequency = models.IntegerField(blank=True, null=True, verbose_name='间隔')
unit = models.CharField(max_length=50, blank=True, null=True, verbose_name='单位', choices=UNIT_CHOICE)
startTime = models.DateTimeField(max_length=50, verbose_name='开始时间')
endTime = models.DateTimeField(max_length=50, verbose_name='结束时间')
def __unicode__(self):
return self.name
def __str__(self):
return self.name
class Meta:
verbose_name = '用例定时任务'
verbose_name_plural = '用例定时任务管理'
class AutomationTaskRunTime(models.Model):
"""
用例执行开始和结束时间
"""
id = models.AutoField(primary_key=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE, verbose_name='项目')
startTime = models.CharField(max_length=50, verbose_name='开始时间')
host = models.CharField(max_length=1024, null=True, blank=True, verbose_name='测试地址')
elapsedTime = models.CharField(max_length=50, verbose_name='结束时间')
class Meta:
verbose_name = '用例任务执行时间'
verbose_name_plural = '用例任务执行时间'
class AutomationCaseTestResult(models.Model):
"""
任务执行结果
"""
id = models.AutoField(primary_key=True)
automationCaseApi = models.ForeignKey(AutomationCaseApi, on_delete=models.CASCADE, verbose_name='接口'
, related_name="auto_result")
header = models.CharField(max_length=1024, blank=True, null=True, verbose_name='请求头')
parameter = models.TextField(blank=True, null=True, verbose_name='请求参数')
result = models.CharField(max_length=50, verbose_name='测试结果', choices=RESULT_CHOICE)
httpStatus = models.CharField(max_length=50, blank=True, null=True, verbose_name='http状态', choices=HTTP_CODE_CHOICE)
responseHeader = models.TextField(blank=True, null=True, verbose_name='返回头')
responseData = models.TextField(blank=True, null=True, verbose_name='实际返回内容')
testTime = models.CharField(max_length=128, null=True, blank=True, verbose_name='测试时间')
def __unicode__(self):
return self.httpStatus
class Meta:
verbose_name = '自动测试结果'
verbose_name_plural = '自动测试结果管理'
class AutomationReportSendConfig(models.Model):
"""
报告发送人配置
"""
id = models.AutoField(primary_key=True)
project = models.OneToOneField(Project, on_delete=models.CASCADE, verbose_name="项目")
reportFrom = models.EmailField(max_length=1024, blank=True, null=True, verbose_name="发送人邮箱")
mailUser = models.CharField(max_length=1024, blank=True, null=True, verbose_name="用户名")
mailPass = models.CharField(max_length=1024, blank=True, null=True, verbose_name="口令")
mailSmtp = models.CharField(max_length=1024, blank=True, null=True, verbose_name="邮箱服务器")
def __unicode__(self):
return self.reportFrom
class Meta:
verbose_name = "邮件发送配置"
verbose_name_plural = "邮件发送配置"
class VisitorsRecord(models.Model):
"""
访客记录
"""
id = models.AutoField(primary_key=True)
formattedAddress = models.CharField(max_length=1024, blank=True, null=True, verbose_name="访客地址")
country = models.CharField(max_length=50, blank=True, null=True, verbose_name="国家")
province = models.CharField(max_length=50, blank=True, null=True, verbose_name="省份")
city = models.CharField(max_length=50, blank=True, null=True, verbose_name="城市")
district = models.CharField(max_length=50, blank=True, null=True, verbose_name="县级")
township = models.CharField(max_length=50, blank=True, null=True, verbose_name="镇")
street = models.CharField(max_length=50, blank=True, null=True, verbose_name="街道")
number = models.CharField(max_length=50, blank=True, null=True, verbose_name="门牌号")
success = models.CharField(max_length=50, blank=True, null=True, verbose_name="成功")
reason = models.CharField(max_length=1024, blank=True, null=True, verbose_name="原因")
callTime = models.DateTimeField(auto_now_add=True, verbose_name="访问时间")
def __unicode__(self):
return self.formattedAddress
class Meta:
verbose_name = "访客"
verbose_name_plural = "访客查看"
18.数据迁移
创建数据库:guoya_api
python manage.py makemigrations
python manage.py migrate
19.在app下创建一个serializers.py文件,对模型创建序列化器
from django.contrib.auth.models import User
from rest_framework import serializers
from rest_framework.authtoken.models import Token
from .models import Project, ProjectDynamic, ProjectMember, GlobalHost, ApiGroupLevelFirst, \
ApiInfo, APIRequestHistory, ApiOperationHistory, AutomationGroupLevelFirst, \
AutomationTestCase, AutomationCaseApi, AutomationHead, AutomationParameter, AutomationTestTask, \
AutomationTestResult, ApiHead, ApiParameter, ApiResponse, ApiParameterRaw, AutomationParameterRaw, \
AutomationResponseJson, AutomationTaskRunTime, AutomationCaseTestResult, AutomationReportSendConfig
class TokenSerializer(serializers.ModelSerializer):
"""
用户信息序列化
"""
first_name = serializers.CharField(source="user.first_name")
last_name = serializers.CharField(source="user.last_name")
phone = serializers.CharField(source="user.user.phone")
email = serializers.CharField(source="user.email")
date_joined = serializers.CharField(source="user.date_joined")
class Meta:
model = Token
fields = ('first_name', 'last_name', 'phone', 'email', 'key', 'date_joined')
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'first_name')
class ProjectDeserializer(serializers.ModelSerializer):
"""
项目信息反序列化
"""
class Meta:
model = Project
fields = ('id', 'name', 'version', 'type', 'status', 'LastUpdateTime', 'createTime', 'description', 'user')
class ProjectSerializer(serializers.ModelSerializer):
"""
项目信息序列化
"""
apiCount = serializers.SerializerMethodField()
dynamicCount = serializers.SerializerMethodField()
memberCount = serializers.SerializerMethodField()
LastUpdateTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
createTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
user = serializers.CharField(source='user.first_name')
class Meta:
model = Project
fields = ('id', 'name', 'version', 'type', 'status', 'LastUpdateTime', 'createTime', 'apiCount',
'dynamicCount', 'memberCount', 'description', 'user')
def get_apiCount(self, obj):
return obj.api_project.all().count()
def get_dynamicCount(self, obj):
return obj.dynamic_project.all().count()
def get_memberCount(self, obj):
return obj.member_project.all().count()
class ProjectDynamicDeserializer(serializers.ModelSerializer):
"""
项目动态信息反序列化
"""
class Meta:
model = ProjectDynamic
fields = ('id', 'project', 'time', 'type', 'operationObject', 'user', 'description')
class ProjectDynamicSerializer(serializers.ModelSerializer):
"""
项目动态信息序列化
"""
operationUser = serializers.CharField(source='user.first_name')
time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
class Meta:
model = ProjectDynamic
fields = ('id', 'time', 'type', 'operationObject', 'operationUser', 'description')
class ProjectMemberDeserializer(serializers.ModelSerializer):
"""
项目成员信息反序列化
"""
class Meta:
model = ProjectMember
fields = ('id', 'permissionType', 'project', 'user')
class ProjectMemberSerializer(serializers.ModelSerializer):
"""
项目成员信息序列化
"""
username = serializers.CharField(source='user.first_name')
userPhone = serializers.CharField(source='user.user.phone')
userEmail = serializers.CharField(source='user.email')
class Meta:
model = ProjectMember
fields = ('id', 'permissionType', 'username', 'userPhone', 'userEmail')
class GlobalHostSerializer(serializers.ModelSerializer):
"""
host信息序列化
"""
class Meta:
model = GlobalHost
fields = ('id', 'project_id', 'name', 'host', 'status', 'description')
class ApiGroupLevelFirstSerializer(serializers.ModelSerializer):
"""
接口一级分组信息序列化
"""
class Meta:
model = ApiGroupLevelFirst
fields = ('id', 'project_id', 'name')
class ApiGroupLevelFirstDeserializer(serializers.ModelSerializer):
"""
接口一级分组信息反序列化
"""
class Meta:
model = ApiGroupLevelFirst
fields = ('id', 'project_id', 'name')
class ApiHeadSerializer(serializers.ModelSerializer):
"""
接口请求头序列化
"""
class Meta:
model = ApiHead
fields = ('id', 'api', 'name', 'value')
class ApiHeadDeserializer(serializers.ModelSerializer):
"""
接口请求头反序列化
"""
class Meta:
model = ApiHead
fields = ('id', 'api', 'name', 'value')
class ApiParameterSerializer(serializers.ModelSerializer):
"""
接口请求参数序列化
"""
class Meta:
model = ApiParameter
fields = ('id', 'api', 'name', 'value', '_type', 'required', 'restrict', 'description')
class ApiParameterDeserializer(serializers.ModelSerializer):
"""
接口请求参数反序列化
"""
class Meta:
model = ApiParameter
fields = ('id', 'api', 'name', 'value', '_type', 'required', 'restrict', 'description')
class ApiParameterRawSerializer(serializers.ModelSerializer):
"""
接口请求参数源数据序列化
"""
class Meta:
model = ApiParameterRaw
fields = ('id', 'api', 'data')
class ApiParameterRawDeserializer(serializers.ModelSerializer):
"""
接口请求参数源数据序列化
"""
class Meta:
model = ApiParameterRaw
fields = ('id', 'api', 'data')
class ApiResponseSerializer(serializers.ModelSerializer):
"""
接口返回参数序列化
"""
class Meta:
model = ApiResponse
fields = ('id', 'api', 'name', 'value', '_type', 'required', 'description')
class ApiResponseDeserializer(serializers.ModelSerializer):
"""
接口返回参数序列化
"""
class Meta:
model = ApiResponse
fields = ('id', 'api', 'name', 'value', '_type', 'required', 'description')
class ApiInfoSerializer(serializers.ModelSerializer):
"""
接口详细信息序列化
"""
lastUpdateTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
headers = ApiHeadSerializer(many=True, read_only=True)
requestParameter = ApiParameterSerializer(many=True, read_only=True)
response = ApiResponseSerializer(many=True, read_only=True)
requestParameterRaw = ApiParameterRawSerializer(many=False, read_only=True)
userUpdate = serializers.CharField(source='userUpdate.first_name')
class Meta:
model = ApiInfo
fields = ('id', 'apiGroupLevelFirst', 'name', 'httpType', 'requestType', 'apiAddress', 'headers',
'requestParameterType', 'requestParameter', 'requestParameterRaw', 'status',
'response', 'mockCode', 'data', 'lastUpdateTime', 'userUpdate', 'description')
class ApiInfoDeserializer(serializers.ModelSerializer):
"""
接口详细信息序列化
"""
class Meta:
model = ApiInfo
fields = ('id', 'project_id', 'name', 'httpType',
'requestType', 'apiAddress', 'requestParameterType', 'status',
'mockCode', 'data', 'lastUpdateTime', 'userUpdate', 'description')
class ApiInfoDocSerializer(serializers.ModelSerializer):
"""
接口详细信息序列化
"""
First = ApiInfoSerializer(many=True, read_only=True)
class Meta:
model = ApiGroupLevelFirst
fields = ('id', 'name', 'First')
class ApiInfoListSerializer(serializers.ModelSerializer):
"""
接口信息序列化
"""
lastUpdateTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
userUpdate = serializers.CharField(source='userUpdate.first_name')
class Meta:
model = ApiInfo
fields = ('id', 'name', 'requestType', 'apiAddress', 'mockStatus', 'lastUpdateTime', 'userUpdate')
class APIRequestHistorySerializer(serializers.ModelSerializer):
"""
接口请求历史信息序列化
"""
requestTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
class Meta:
model = APIRequestHistory
fields = ('id', 'requestTime', 'requestType', 'requestAddress', 'httpCode')
class APIRequestHistoryDeserializer(serializers.ModelSerializer):
"""
接口请求历史信息反序列化
"""
class Meta:
model = APIRequestHistory
fields = ('id', 'api_id', 'requestTime', 'requestType', 'requestAddress', 'httpCode')
class ApiOperationHistorySerializer(serializers.ModelSerializer):
"""
接口操作历史信息序列化
"""
time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
user = serializers.CharField(source='user.first_name')
class Meta:
model = ApiOperationHistory
fields = ('id', 'user', 'time', 'description')
class ApiOperationHistoryDeserializer(serializers.ModelSerializer):
"""
接口操作历史信息反序列化
"""
class Meta:
model = ApiOperationHistory
fields = ('id', 'apiInfo', 'user', 'time', 'description')
class AutomationGroupLevelFirstSerializer(serializers.ModelSerializer):
"""
自动化用例一级分组信息序列化
"""
class Meta:
model = AutomationGroupLevelFirst
fields = ('id', 'project_id', 'name')
class AutomationTestCaseSerializer(serializers.ModelSerializer):
"""
自动化用例信息序列化
"""
updateTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
createUser = serializers.CharField(source='user.first_name')
class Meta:
model = AutomationTestCase
fields = ('id', 'automationGroupLevelFirst', 'caseName', 'createUser',
'description', 'updateTime')
class AutomationTestCaseDeserializer(serializers.ModelSerializer):
"""
自动化用例信息反序列化
"""
class Meta:
model = AutomationTestCase
fields = ('id', 'project_id', 'automationGroupLevelFirst', 'caseName', 'user',
'description', 'updateTime')
class AutomationHeadSerializer(serializers.ModelSerializer):
"""
自动化用例接口请求头信息序列化
"""
class Meta:
model = AutomationHead
fields = ('id', 'automationCaseApi', 'name', 'value', 'interrelate')
class AutomationHeadDeserializer(serializers.ModelSerializer):
"""
自动化用例接口请求头信息反序列化
"""
class Meta:
model = AutomationHead
fields = ('id', 'automationCaseApi_id', 'name', 'value', 'interrelate')
class AutomationParameterSerializer(serializers.ModelSerializer):
"""
自动化用例接口请求参数信息序列化
"""
class Meta:
model = AutomationParameter
fields = ('id', 'automationCaseApi', 'name', 'value', 'interrelate')
class AutomationParameterDeserializer(serializers.ModelSerializer):
"""
自动化用例接口请求参数信息反序列化
"""
class Meta:
model = AutomationParameter
fields = ('id', 'automationCaseApi_id', 'name', 'value', 'interrelate')
class AutomationParameterRawSerializer(serializers.ModelSerializer):
"""
接口请求参数源数据序列化
"""
class Meta:
model = AutomationParameterRaw
fields = ('id', 'automationCaseApi', 'data')
class AutomationParameterRawDeserializer(serializers.ModelSerializer):
"""
接口请求参数源数据反序列化
"""
class Meta:
model = AutomationParameterRaw
fields = ('id', 'automationCaseApi_id', 'data')
class AutomationResponseJsonSerializer(serializers.ModelSerializer):
"""
返回JSON参数序列化
"""
class Meta:
model = AutomationResponseJson
fields = ('id', 'automationCaseApi', 'name', 'tier')
class AutomationResponseJsonDeserializer(serializers.ModelSerializer):
"""
返回JSON参数反序列化
"""
class Meta:
model = AutomationResponseJson
fields = ('id', 'automationCaseApi', 'name', 'tier')
class CorrelationDataSerializer(serializers.ModelSerializer):
"""
关联数据序列化
"""
response = AutomationResponseJsonSerializer(many=True, read_only=True)
class Meta:
model = AutomationCaseApi
fields = ("id", "name", "response")
class AutomationCaseApiSerializer(serializers.ModelSerializer):
"""
自动化用例接口详细信息序列化
"""
header = AutomationHeadSerializer(many=True, read_only=True)
parameterList = AutomationParameterSerializer(many=True, read_only=True)
parameterRaw = AutomationParameterRawSerializer(many=False, read_only=True)
class Meta:
model = AutomationCaseApi
fields = ('id', 'name', 'httpType', 'requestType', 'apiAddress', 'header', 'requestParameterType', 'formatRaw',
'parameterList', 'parameterRaw', 'examineType', 'httpCode', 'responseData')
class AutomationCaseDownloadSerializer(serializers.ModelSerializer):
"""
下载用例读取数据序列
"""
# api = AutomationCaseApiSerializer(many=True, read_only=True)
updateTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
# automationGroupLevelFirst = serializers.CharField(source='automationGroupLevelFirst.name')
user = serializers.CharField(source="user.first_name")
api = serializers.SerializerMethodField()
class Meta:
model = AutomationTestCase
fields = ('caseName', 'user', 'updateTime', 'api')
def get_api(self, obj):
return AutomationCaseApiSerializer(
AutomationCaseApi.objects.filter(automationTestCase=obj).order_by("id"),
many=True
).data
class AutomationCaseDownSerializer(serializers.ModelSerializer):
"""
下载用例读取数据序列
"""
automationGroup = AutomationCaseDownloadSerializer(many=True, read_only=True)
class Meta:
model = AutomationGroupLevelFirst
fields = ("name", "automationGroup")
class AutomationCaseApiDeserializer(serializers.ModelSerializer):
"""
自动化用例接口详细信息反序列化
"""
class Meta:
model = AutomationCaseApi
fields = ('id', 'automationTestCase_id', 'name', 'httpType', 'requestType', 'apiAddress', 'requestParameterType',
'formatRaw', 'examineType', 'httpCode', 'responseData')
class AutomationCaseApiListSerializer(serializers.ModelSerializer):
"""
自动化用例接口列表信息序列化
"""
class Meta:
model = AutomationCaseApi
fields = ('id', 'name', 'requestType', 'apiAddress')
class AutomationTestTaskSerializer(serializers.ModelSerializer):
"""
定时任务信息序列化
"""
startTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
endTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
class Meta:
model = AutomationTestTask
fields = ('id', 'project', 'Host', 'name', 'type', 'frequency', 'unit', 'startTime', 'endTime')
class AutomationTestTaskDeserializer(serializers.ModelSerializer):
"""
定时任务信息反序列化
"""
class Meta:
model = AutomationTestTask
fields = ('id', 'project_id', 'Host_id', 'name', 'type', 'frequency', 'unit', 'startTime', 'endTime')
class AutomationTestReportSerializer(serializers.ModelSerializer):
"""
测试报告测试结果信息序列化
"""
result = serializers.CharField(source='test_result.result')
host = serializers.CharField(source='test_result.host')
parameter = serializers.CharField(source='test_result.parameter')
httpStatus = serializers.CharField(source='test_result.httpStatus')
responseData = serializers.CharField(source='test_result.responseData')
automationTestCase = serializers.CharField(source='automationTestCase.caseName')
testTime = serializers.CharField(source='test_result.testTime')
class Meta:
model = AutomationCaseApi
fields = ('id', 'automationTestCase', 'name', 'host', 'httpType', 'requestType', 'apiAddress', 'examineType',
'result', 'parameter', 'httpStatus', 'responseData', 'testTime')
class AutomationTaskRunTimeSerializer(serializers.ModelSerializer):
"""
任务执行时间
"""
startTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
project = serializers.CharField(source='project.name')
class Meta:
model = AutomationTaskRunTime
fields = ('id', 'project', 'startTime', 'elapsedTime', 'host')
class AutomationTestResultSerializer(serializers.ModelSerializer):
"""
手动测试结果详情序列化
"""
testTime = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
class Meta:
model = AutomationTestResult
fields = ('id', 'url', 'requestType', 'header', 'parameter', 'statusCode', 'examineType', 'data',
'result', 'httpStatus', 'responseData', 'testTime')
class AutomationAutoTestResultSerializer(serializers.ModelSerializer):
"""
自动测试结果详情序列化
"""
name = serializers.CharField(source='automationCaseApi.name')
httpType = serializers.CharField(source='automationCaseApi.httpType')
requestType = serializers.CharField(source='automationCaseApi.requestType')
apiAddress = serializers.CharField(source='automationCaseApi.apiAddress')
examineType = serializers.CharField(source='automationCaseApi.examineType')
automationTestCase = serializers.CharField(source='automationCaseApi.automationTestCase')
class Meta:
model = AutomationCaseTestResult
fields = ('id', 'automationTestCase', 'name', 'httpType', 'header', 'requestType', 'apiAddress', 'examineType',
'result', 'parameter', 'httpStatus', 'responseHeader', 'responseData', 'testTime')
class AutomationTestLatelyTenTimeSerializer(serializers.ModelSerializer):
"""
最近10次测试结果
"""
class Meta:
model = AutomationTaskRunTime
fields = ("id", "startTime")
class AutomationReportSendConfigSerializer(serializers.ModelSerializer):
"""
发送人配置序列
"""
project = serializers.CharField(source='project.name')
class Meta:
model = AutomationReportSendConfig
fields = ("id", "project", 'reportFrom', 'mailUser', 'mailPass', 'mailSmtp')
class AutomationReportSendConfigDeserializer(serializers.ModelSerializer):
"""
发送人配置反序列
"""
class Meta:
model = AutomationReportSendConfig
fields = ("id", "project_id", 'reportFrom', 'mailUser', 'mailPass', 'mailSmtp')
作业:配合swagger熟悉项目结构,方便开发后台业务
网友评论