數據庫模型圖
創建app
根據上面的數據庫設計,創建9個app
configures
debugtalks
envs
interfaces
projects
reports
testsuits
testcases
user
完成註冊
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'corsheaders',
'configures.apps.ConfiguresConfig',
'debugtalks.apps.DebugtalksConfig',
'envs.apps.EnvsConfig',
'interfaces.apps.InterfacesConfig',
'projects.apps.ProjectsConfig',
'reports.apps.ReportsConfig',
'testsuits.apps.TestsuitsConfig',
'testcases.apps.TestcasesConfig',
'user.apps.UserConfig',
]
抽象數據庫基類
從數據庫模型圖可以看出,有很多部分都重複了
create_time
update_time
is_delete
from django.db import models
class BaseModel(models.Model):
"""
數據庫表公共字段
"""
create_time = models.DateTimeField(auto_now_add=True, verbose_name="創建時間", help_text="創建時間")
update_time = models.DateTimeField(auto_now=True, verbose_name="更新時間", help_text="更新時間")
is_delete = models.BooleanField(default=False, verbose_name="邏輯刪除", help_text="邏輯刪除")
class Meta:
# 爲抽象模型類, 用於其他模型來繼承,數據庫遷移時不會創建BaseModel表
abstract = True
verbose_name = "公共字段表"
db_table = 'BaseModel'
default=False
默認情況下不刪除
各模塊的模型
configures
# configures.models.Configures
from django.db import models
from utils.base_models import BaseModel
class Configures(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('配置名稱', max_length=50, help_text='配置名稱')
interface = models.ForeignKey('interfaces.Interfaces',
on_delete=models.CASCADE,
related_name='configures',
help_text='所屬接口')
author = models.CharField('編寫人員', max_length=50, help_text='編寫人員')
request = models.TextField('請求信息', help_text='請求信息')
class Meta:
db_table = 'tb_configures'
verbose_name = '配置信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
debugtalks
# debugtalks.models.DebugTalks
from django.db import models
from utils.base_models import BaseModel
class DebugTalks(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('debugtalk文件名稱', max_length=200, default='debugtalk.py', help_text='debugtalk文件名稱')
debugtalk = models.TextField(null=True, default='#debugtalk.py', help_text='debugtalk.py文件')
project = models.OneToOneField('projects.Projects', on_delete=models.CASCADE,
related_name='debugtalks', help_text='所屬項目')
class Meta:
db_table = 'tb_debugtalks'
verbose_name = 'debugtalk.py文件'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
interfaces
# interfaces.models.Interfaces
from django.db import models
from utils.base_models import BaseModel
class Interfaces(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('接口名稱', max_length=200, unique=True, help_text='接口名稱')
project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
related_name='interfaces', help_text='所屬項目')
tester = models.CharField('測試人員', max_length=50, help_text='測試人員')
desc = models.CharField('簡要描述', max_length=200, null=True, blank=True, help_text='簡要描述')
class Meta:
db_table = 'tb_interfaces'
verbose_name = '接口信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
projects
# projects.models.Projects
from django.db import models
from utils.base_models import BaseModel
class Projects(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('項目名稱', max_length=200, unique=True, help_text='項目名稱')
leader = models.CharField('負責人', max_length=50, help_text='項目負責人')
tester = models.CharField('測試人員', max_length=50, help_text='項目測試人員')
programmer = models.CharField('開發人員', max_length=50, help_text='開發人員')
publish_app = models.CharField('發佈應用', max_length=100, help_text='發佈應用')
desc = models.CharField('簡要描述', max_length=200, null=True, blank=True, default='', help_text='簡要描述')
class Meta:
db_table = 'tb_projects'
verbose_name = '項目信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
reports
# reports.models.Reports
from django.db import models
from utils.base_models import BaseModel
class Reports(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('報告名稱', max_length=200, unique=True, help_text='報告名稱')
result = models.BooleanField('執行結果', default=1, help_text='執行結果') # 1爲成功, 0爲失敗
count = models.IntegerField('用例總數', help_text='總用例數')
success = models.IntegerField('成功總數', help_text='成功總數')
html = models.TextField('報告HTML源碼', help_text='報告HTML源碼', null=True, blank=True, default='')
summary = models.TextField('報告詳情', help_text='報告詳情', null=True, blank=True, default='')
class Meta:
db_table = 'tb_reports'
verbose_name = '測試報告'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
testcases
# testcases.models.Testcases
from django.db import models
from utils.base_models import BaseModel
class Testcases(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('用例名稱', max_length=50, unique=True, help_text='用例名稱')
interface = models.ForeignKey('interfaces.Interfaces', on_delete=models.CASCADE,
help_text='所屬接口')
# include = models.ForeignKey('', on_delete=models.SET_NULL, null=True, related_name='testcases')
include = models.TextField('前置', null=True, help_text='用例執行前置順序')
author = models.CharField('編寫人員', max_length=50, help_text='編寫人員')
request = models.TextField('請求信息', help_text='請求信息')
class Meta:
db_table = 'tb_testcases'
verbose_name = '用例信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
testsuits
# testsuits.models.Testsuits
from django.db import models
from utils.base_models import BaseModel
class Testsuits(BaseModel):
id = models.AutoField(verbose_name='id主鍵', primary_key=True, help_text='id主鍵')
name = models.CharField('套件名稱', max_length=200, unique=True, help_text='套件名稱')
project = models.ForeignKey('projects.Projects', on_delete=models.CASCADE,
related_name='testsuits', help_text='所屬項目')
# include = models.TextField(null=False)
include = models.TextField('包含的接口', null=False, help_text='包含的接口')
class Meta:
db_table = 'tb_testsuits'
verbose_name = '套件信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
projects
需求
刪除項目時,只進行邏輯刪除
獲取項目列表信息時,要求能獲取此項目下的「接口總數」,「用例總數」,「配置總數」,「套件總數」,同時輸出創建時間,格式爲2019-11-05 11:43:00
要求提供獲取此項目下的所有項目名的接口
要求提供獲取此項目下的所有接口信息的接口
序列化器
from rest_framework import serializers
from .models import Projects
from debugtalks.models import DebugTalks
from interfaces.models import Interfaces
class ProjectModelSerializer(serializers.ModelSerializer):
class Meta:
model = Projects
exclude = ('update_time', 'is_delete')
extra_kwargs = {
'create_time': {
'read_only': True
}
}
def create(self, validated_data):
project_obj = super().create(validated_data)
DebugTalks.objects.create(project=project_obj)
return project_obj
class ProjectNameSerializer(serializers.ModelSerializer):
class Meta:
model = Projects
fields = ('id', 'name')
class InterfaceNameSerializer(serializers.ModelSerializer):
class Meta:
model = Interfaces
fields = ('id', 'name', 'tester')
class InterfacesByProjectIdSerializer(serializers.ModelSerializer):
interfaces_set = InterfaceNameSerializer(read_only=True, many=True)
class Meta:
model = Projects
fields = ('id', 'interfaces_set')
視圖
繼承 ModelViewSet
from rest_framework.viewsets import ModelViewSet
from rest_framework import permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.exceptions import NotFound
from . import serializer
from .models import Projects
from .utils import get_count_by_project
from interfaces.models import Interfaces
class ProjectsViewSet(ModelViewSet):
"""
list:
返回項目(多個)列表數據
create:
創建項目
retrieve:
返回項目(單個)詳情數據
update:
更新(全)項目
partial_update:
更新(部分)項目
destroy:
刪除項目
names:
返回所有項目ID和名稱
interfaces:
返回某個項目的所有接口信息(ID和名稱)
"""
queryset = Projects.objects.filter(is_delete=False)
serializer_class = serializer.ProjectModelSerializer
permission_classes = (permissions.IsAuthenticated,)
ordering_fields = ('id', 'name')
def perform_destroy(self, instance):
instance.is_delete = True
instance.save() # 邏輯刪除
@action(methods=['get'], detail=False)
def names(self, request, *args, **kwargs):
queryset = self.get_queryset()
serializer = serializer.ProjectNameSerializer(instance=queryset, many=True)
return Response(serializer.data)
@action(methods=['get'], detail=True)
def interfaces(self, request, pk=None):
interface_objs = Interfaces.objects.filter(project_id=pk, is_delete=False)
one_list = []
for obj in interface_objs:
one_list.append({
'id': obj.id,
'name': obj.name
})
return Response(data=one_list)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
datas = serializer.data
datas = get_count_by_project(datas)
return self.get_paginated_response(datas)
serializer = self.get_serializer(queryset, many=True)
datas = serializer.data
datas = get_count_by_project(datas)
return Response(datas)