models模块学习:
项目管理表:
项目名称 | 项目描述 | 创建人 |
---|---|---|
CharField | TextField | CharField |
class Project(models.Model):
name = models.CharField(max_length=20, null=False)
remark = models.TextField(null=True)
creator = models.CharField(max_length=20, null=False, default='朵法拉')
createTime = models.DateTimeField(default=timezone.now)
然后对表进行修饰:
class Meta:
db_table = 'project' #表名设置为project
verbose_name = '项目管理' #给项目起个名字,在后台能显示这个名字
verbose_name_plural = '项目管理' #当项目管理的项目为复数时,显示的名字
下面是对前台写入到数据库表的判断:
def clean(self):
name = self.name.strip() if self.name else "" #如果传进来的内容存在,就去掉内容中的空格,否则返回空字符串
if 0 >= len(name) or len(name) > 20: #长度在0到20之间合格,之外就提示无效
raise ValidationError({'name': '无效的项目名称'})
这是为了对前台输入的内容进行判断,及时提醒。
strip(),该函数的作用是去除字符串开头和结尾处指定的字符,不会去除字符串中间对应的字符;
页面管理表:
项目ID | 页面名称 | 页面描述 | 创建时间 |
---|---|---|---|
IntegerField | CharField | TextField | DateTimeField |
class Page(models.Model):
projectId = models.IntegerField()
name = models.CharField(max_length=20, null=False)
remark = models.TextField(null=True)
createTime = models.DateTimeField(default=timezone.now)
然后对表进行修饰:
class Meta:
db_table = 'page'
verbose_name = '页面管理'
verbose_name_plural = '页面管理'
效果同项目管理。
def clean(self):
name = self.name.strip() if self.name else ""
projectId = int(self.projectId) if self.projectId and str(self.projectId).isdigit() else 0 #项目ID如果存在而且id转化为字符串后都是数字字符串,就转化为整型;否则就是0
if 0 >= len(name) or len(name) > 20:
raise ValidationError({'name': '无效的页面名称'})
if projectId < 1:
raise ValidationError({'projectId': '无效的项目Id'})
因为从前端传过来的信息格式可以是整形可以是字符串,所以要转化。首先都转化为字符串用isdigit()函数判断,字符串是否都是数字组成,如果是就成功,不是就是0。然后再对长度进行判断。页面名称0-20个字才行,ID>=1才行。
元素管理表
项目ID | 页面ID | 元素名称 | 描述 | 创建时间 | 定位类型 | 定位值 |
---|---|---|---|---|---|---|
IntegerField | IntegerField | CharField | TextField | DateTimeField | CharField | CharField |
class Meta这一步和上面一样,就不说啦。
def __str__(self):
return self.name```
如果不加_str_时,在后台页面管理中设置所属项目时,下拉框出现的不是项目名称,而是返回object(0),object(1)。
def clean(self):
name = self.name.strip() if self.name else ""
locator = str(self.locator) if self.locator else ""
by = str(self.by).lower() if self.by else ""
pageId = int(self.pageId) if str(self.pageId).isdigit() else 0
if 0 >= len(name) or len(name) > 20:
raise ValidationError({'name': '无效的元素名称'})
if pageId < 1:
raise ValidationError({'pageId': '无效的页面Id'})
if not by in Element.BY_TYPES:
raise ValidationError({'by': 'by'})
if 0 >= len(locator) or len(locator) > 200:
raise ValidationError({'locator': '无效的定位值'})
下面,重头戏来啦
关键字表
为什么说它重头戏,看看前端关键字管理编辑的界面吧
项目ID | 关键字名称 | 类型 | 包 | 类 | 方法 | 参数 | 步骤 | 创建时间 | 描述 |
---|---|---|---|---|---|---|---|---|---|
IntegerField | CharField | IntegerField | CharField | CharField | CharField | TextField | TextFiel | DateTimeField | TextField |
class Keyword(models.Model):
__KEYWORD_TYPES = {1: "system", 2: "custom"}
projectId = models.IntegerField()
name = models.CharField(max_length=20)
type = models.IntegerField(default=2)
package = models.CharField(max_length=200, null=True)
clazz = models.CharField(max_length=50, null=True)
method = models.CharField(max_length=50, null=True)
params = models.TextField(null=True)
steps = models.TextField(null=True)
createTime = models.DateTimeField(default=timezone.now)
remark = models.TextField(null=True)
class Meta:
db_table = "keyword"
KEYWORD_TYPES里边1代表系统,2代表自定义。params在系统设置的前提下,是向方法clazz需要传入的参数,前端写好传过来参数。就可以调用了。步骤是自定义时设置的。步骤里边可以设置打开url,输入文字,点击搜索的这些流程,一步一步设置好,是把关键字组合起来的一个过程。
def clean(self):
name = self.name.strip() if self.name else ""
projectId = int(self.projectId) if str(self.projectId).isdigit() else 0
package = self.package
clazz = self.clazz
method = self.method
if not str(self.type).isdigit():
raise ValidationError({'type': '无效的操作类型'})
t = int(self.type) #type是前端通过value值传过来的,1和2.
step = self.steps if self.steps else [] #没有steps就是[]
if 0 >= len(name) or len(name) > 20:
raise ValidationError({'name': '无效的关键字名称'})
if projectId < 0:
raise ValidationError({'projectId': '无效的项目Id'})
if t == 1: #1是代表系统
try:
obj = __import__(package, fromlist=[package.split(",")[-1]]) #这是为了导入package包,fromlist参数必须有,不过作用显示不出来,是为了导包正确所用的参数,没有就不能导package包。
except:
raise ValidationError({'package': '无效的引用包'})
try:
obj = getattr(obj, clazz) #这个函数可以返回obj对象的clazz属性,就是用package包里的clazz类
except:
raise ValidationError({'clazz': '无效的引用类'})
try:
getattr(obj, method) #用clazz类中某个method方法
except:
raise ValidationError({'method': '无效的引用方法'})
elif t == 2:
if isinstance(step, str):
import json
step = json.loads(step) #将json字符串解码为python对象
if not isinstance(step, list): #不是列表时,报错
raise ValidationError({'step': '无效的操作步骤 : not list'})
for s in step: #遍历列表
if not isinstance(s, dict): #列表里不是字典时报错
raise ValidationError({'step': '无效的操作步骤'})
if not "keywordId" in s: #字典里没有这个key,报错
raise ValidationError({'step': '无效的操作步骤 : keywordId'})
keywordId = int(s.get("keywordId")) if str(s.get("keywordId")).isdigit() else 0 #这个key对应的值位数字就行
if keywordId < 1:
raise ValidationError({'step': '无效的操作步骤 : keywordId'})
if not ("values" in s and isinstance(s.get("values"), list)):
raise ValidationError({'step': '无效的操作步骤 : values'})
values = s.get("values") #得到的是 [{"isParameter": true, "type": "element", "key": "location", "value": "实现阿是穴"}, {"isParameter": true, "type": "string", "key": "text", "value": "飒飒"}]
for value in values: #遍历里边的字典
try:
Params(value) #后边的方法,对value判断。
except ValueError:
raise ValidationError({'step': '无效的操作步骤 : value'})
else:
raise ValidationError({'type': '无效的操作类型'})
这里很不好理解,params这个属性是做什么的,怎么用,首先它是参数的意思。如下图
比如说send_keys这个方法,它需要知道元素名称,和要输入的内容。在后面要用到。
location是一个名字,用来区分,用处不大。而输入框是这样设置的。
细心的发现了,这里有个参数化,而且前面也是url和text设置的是参数化,名称是url和搜索内容。这个参数化是为了在后边,添加测试数据时用到的。
太神奇了。
代码中,Params(value)是对value的值判断。value是{“isParameter”: true, “type”: “element”, “key”: “location”, “value”: “实现阿是穴”}
不说了,上代码:
class Params:
TYPE_STRING = 'string'
TYPE_ELEMENT = 'element'
TYPE_FILE = 'file'
TYPES = [TYPE_ELEMENT, TYPE_FILE, TYPE_STRING] #type必须是这里边的
def __init__(self, kwargs):
isParameter = kwargs.get("isParameter", False) #有就是True
Type = kwargs.get("type", None)
key = kwargs.get("key", None)
value = kwargs.get("value", None)
if not (Type and isinstance(Type, str)): #type得是str类型
raise ValueError("Params object Type must be str type")
Type = Type.lower()
if Type not in Params.TYPES: #type必须是这里边的
raise ValueError("Params object Type value error")
if isParameter and (not value or str(value).strip() == 0):
raise ValueError("Params Type parameter must has key")
else:
self.Type = Type
self.key = key.strip()
self.value = value
self.isParameter = isParameter
def __dict__(self):
obj = dict()
obj["type"] = self.Type
obj["isParameter"] = self.isParameter
obj["value"] = self.value
obj["key"] = self.key
return obj
这样就能创出来一个含有这些key的字典了。
今天就到这,再见!你努力的样子真TM靓仔!