背景描述
模型
from django.db import models
from interfaces.validate import validate_include
from testcases.models import Testcases
from utils.base_models import BaseModel
from utils.pure_validator import JSONValidator
class Interfaces(BaseModel):
id = models.AutoField(verbose_name='id主键', primary_key=True, help_text='id主键')
name = models.CharField('接口名称', max_length=200, unique=True, blank=False, null=False, help_text='接口名称')
project = models.CharField('接口Path', max_length=200, unique=True, help_text='接口Path')
project = models.ForeignKey('projects.Projects', on_delete=models.PROTECT,
related_name='interfaces', help_text='所属项目')
env = models.ForeignKey('envs.Envs', on_delete=models.PROTECT, null=True, blank=True,
related_name='env', help_text='对应的环境变量', default=None)
project_module = models.ForeignKey('project_module.ProjectModule', on_delete=models.PROTECT,
related_name='interfaces', help_text='接口所属模块',
null=True, blank=True, default=None)
tester = models.CharField('测试人员', max_length=50, help_text='测试人员')
desc = models.TextField('描述', max_length=200, null=True, blank=True, help_text='备注信息')
# 请求类型,请求参数(Params Body Header Cookie Auth 设置),请求示例,响应示例,状态码,备注,状态,自定义字段
REQUEST_TYPE_CHOICES = (
('GET', 'GET'),
('POST', 'POST'),
('PUT', 'PUT'),
('DELETE', 'DELETE'),
('PATCH', 'PATCH')
)
method = models.CharField('请求类型', max_length=10, choices=REQUEST_TYPE_CHOICES, default='get',
help_text='请求类型')
# 请求参数
params = models.JSONField('请求参数', null=True, blank=True, help_text='请求参数', validators=[JSONValidator()])
json = models.JSONField('请求体', null=True, blank=True, help_text='请求Body', validators=[JSONValidator()])
data = models.JSONField('请求表单', null=True, blank=True, help_text='请求表单', validators=[JSONValidator()])
headers = models.JSONField('请求Header', null=True, blank=True, help_text='请求Header',
validators=[JSONValidator()])
cookies = models.JSONField('请求Cookie', null=True, blank=True, help_text='请求Cookie',
validators=[JSONValidator()])
auth = models.CharField('请求Auth', max_length=100, null=True, blank=True, help_text='请求Auth')
response_example = models.TextField('响应示例', null=True, blank=True, help_text='响应示例')
response_status_code = models.CharField('状态码', max_length=10, null=True, blank=True, help_text='状态码')
STATUS_CHOICES = (
('published', '已发布'),
('testing', '测试中'),
('deprecated', '已废弃'),
('developing', '开发中')
)
status = models.CharField('状态', max_length=20, choices=STATUS_CHOICES, default='published')
include = models.JSONField('接口前置信息', help_text='接口前置信息', validators=[validate_include])
class Meta:
db_table = 'tb_interfaces'
verbose_name = '接口信息'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
视图
import logging
from datetime import datetime
from rest_framework import filters
from rest_framework import permissions
from rest_framework import viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from interfaces.models import Interfaces
from project_module.models import ProjectModule
from testcases.models import Testcases
from utils.json_utils import json_utils
from .serializers import InterfacesModelSerializer, TestcasesInterfacesModelSerializer, \
ConfiguresInterfacesModelSerializer, InterfacesRunSerializer
logger = logging.getLogger('Django')
class InterfacesViewSet(viewsets.ModelViewSet):
"""
list:
获取接口列表数据
retrieve:
获取接口详情数据
update:
更新接口信息
names:
获取接口名称
sava_case:
保存接口为用例
"""
queryset = Interfaces.objects.all()
serializer_class = InterfacesModelSerializer
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['=name', '=id', '=tester']
# search_fields = ['name', 'id', 'tester']
ordering_fields = ['id', 'name', 'tester']
permission_classes = [permissions.IsAuthenticated]
Search实现的全量查询
首先我们在视图中,规定了查询字段。
queryset = Interfaces.objects.all()
serializer_class = InterfacesModelSerializer
# 指定筛选和排序后端
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
# 定义搜索字段,'=' 表示精确匹配
search_fields = ['=name', '=id', '=tester']
如果你想改成模糊查询,你可以将 search_fields 的设置改为:
search_fields = ['name', 'id', 'tester']
代码语法
search_fields
属性在 Django REST framework 中用于指定哪些字段应该被SearchFilter
后端用于搜索查询。以下是各种前缀和后缀的详细解释:
- ‘^’:此前缀表示字段应以搜索项开头。例如,如果你有一个名为 ‘name’ 的字段,并且设置为
'^name'
,那么搜索字符串 ‘abc’ 将匹配任何名称以 ‘abc’ 开头的项目。- ‘=’:此前缀表示字段应完全匹配搜索项。例如,如你有一个名为 ‘name’ 的字段,并且设置为
'=name'
,那么搜索字符串 ‘abc’ 将只匹配名称完全等于 ‘abc’ 的项目。- ‘@’:此前缀仅适用于文本字段。它表示字段应与搜索项进行全文搜索(仅适用于支持全文搜索的数据库)。
$
:此前缀表示字段应完全匹配搜索项。例如,如你有一个名为 ‘name’ 的字段,并且设置为'name$'
,那么搜索字符串 ‘abc’ 将只匹配名称以 ‘abc’ 结尾的项目。如果不使用任何符号,将默认进行包含(即模糊)匹配。例如,如果你设置为
'name'
,那么搜索字符串 ‘abc’ 将匹配任何名称中包含 ‘abc’ 的项。注意:这些都是基于 ORM 查询用语实现的,由于 ORM 查询用语依赖于数据库引擎,所以在某些数据库中可能无法工作。
/swagger/json/
精确匹配
由于之前配置了name
为查询字段,则输入对应的值,可以如图精准查询到值。
反向示例
若输入部分则无法查询到
由于之前没有配置desc
,所以没法查询到对应的值
此处为反向示例,下面的内容由于篇幅原因不在一一赘述。
部分匹配
# 精准匹配
# search_fields = ['=name', '=id', '=tester']
# 部分匹配
search_fields = ['name', '=id', '^desc']
-
'name'
:这个设置表示在name
字段上执行包含搜索。也就是说,如果你所提供的搜索字词出现在name
字段中的任何位置,该项都会被返回。例如,如果搜索 ‘abc’,将会返回所有name
字段中包含 ‘abc’ 的项目。name
-
'=id'
:这里的等号前缀表示只有当id
字段的值和搜寻字词完全匹配时才返回结果。例如,如果搜索词为 ‘123’,那么仅当id
字段完全等于 ‘123’ 的项目才会被返回。id
-
'desc'
:这个设置意味着搜索将匹配以搜索字词开头的desc
字段。例如,如果搜索 ‘intro’,那么所有desc
字段以 ‘intro’ 开头的项目都会被返回。desc
匹配以xxx结尾,作者模拟出现一些问题。