luoxinmoli

一、pycharm 从git拉取代码

  • 1、VCS--Get Versoin Controll

  • 2、具体配置内容

二、执行manage.py

1、pycharm路径

   

  • 2、创建项目startapp +项目名称
  • 例如:startapp sksystem
  • 3、为新创建的项目新增urls.py
  • earth/urls.py 增加路径
 1 from django.contrib import admin
 2 from django.urls import path, include
 3 from sksystem import urls as sksUrls
 4 from example import urls as urls
 5 
 6 
 7 urlpatterns = [
 8     path(\'admin/\', admin.site.urls),
 9     path(\'example/\',include(urls)),
10     path(\'api/\', include(sksUrls)),  # 例子url,访问的时候就是/example/book
11 ]

 

或者这样修改,将不用的example去除

1 from django.contrib import admin
2 from django.urls import path, include
3 
4 #from sksystem import urls
5 
6 urlpatterns = [
7     path(\'admin/\', admin.site.urls),
8     path(\'api/\', include(urls)),  # 例子url,访问的时候就是/example/book
9 ]

 

 4、settings.py 增加新增的项目

三、数据库设计:

 

 

 

 

 

 

 

 

models.py

  1 from django.db import models
  2 from utils import tools
  3 from earth import settings
  4 
  5 
  6 # Create your models here.
  7 
  8 
  9 class BaseModel(models.Model):
 10     \'\'\'公共字段\'\'\'
 11     is_delete_choice = (
 12         (0, \'删除\'),
 13         (1, \'正常\')
 14     )
 15     is_delete = models.SmallIntegerField(choices=is_delete_choice, default=1, verbose_name=\'是否被删除\')
 16     create_time = models.DateTimeField(verbose_name=\'创建时间\', auto_now_add=True)  # auto_now_add的意思,插入数据的时候,自动取当前时间
 17     update_time = models.DateTimeField(verbose_name=\'修改时间\', auto_now=True)  # 修改数据的时候,时间会自动变
 18 
 19     class Meta:
 20         abstract = True  # 只是用来继承的,不会创建这个表
 21 
 22 
 23 class User(BaseModel):
 24     \'\'\'用户表\'\'\'
 25     phone = models.CharField(verbose_name=\'手机号\', max_length=11, unique=True)
 26     email = models.EmailField(verbose_name=\'邮箱\', max_length=25, unique=True)
 27     password = models.CharField(verbose_name=\'密码\', max_length=32)
 28     username = models.CharField(verbose_name=\'昵称\', default=\'Python小学生\', max_length=20)
 29 
 30     @staticmethod
 31     def make_password(raw_password):
 32         \'\'\'生成密码\'\'\'
 33         before_password = \'%s%s\' % (raw_password, settings.SECRET_KEY)  # 生成密码的算法,可以自己改
 34         after_password = tools.md5(before_password)
 35         return after_password
 36 
 37     def set_password(self, raw_password):
 38         \'\'\'设置密码\'\'\'
 39         self.password = self.make_password(raw_password)
 40 
 41     def check_password(self, raw_password):
 42         \'\'\'校验登录密码\'\'\'
 43         return self.make_password(raw_password) == self.password
 44 
 45     def __str__(self):
 46         return self.username
 47 
 48     class Meta:
 49         verbose_name = \'用户表\'
 50         verbose_name_plural = verbose_name
 51         db_table = \'user\'
 52 
 53 class Parameter(BaseModel):#继承BaseModel
 54     \'\'\'全局参数表\'\'\'
 55     name = models.CharField(verbose_name=\'参数名\', max_length=100, unique=True)#unique=True 唯一
 56     desc = models.CharField(verbose_name=\'描述\', max_length=200, null=True)#null=True允许传空
 57     value = models.CharField(verbose_name=\'参数值\', max_length=100)
 58 
 59     def __str__(self):
 60         return self.name
 61 
 62     class Meta:
 63         verbose_name = \'全局参数\'
 64         verbose_name_plural = verbose_name
 65         db_table = \'parameter\'
 66         ordering = [\'-id\']  # 按照id倒排。
 67 
 68 
 69 class Project(BaseModel):
 70     \'\'\'项目表\'\'\'
 71     name = models.CharField(verbose_name=\'项目名\', max_length=100, unique=True)
 72     desc = models.CharField(verbose_name=\'描述\', max_length=200, null=True)
 73     host = models.CharField(verbose_name=\'域名\', max_length=1024)
 74     user = models.ForeignKey(User, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'创建者\')
 75     #on_delete=models.DO_NOTHING 当删除的时候不做任何事情 db_constraint=False 不是真正的去创建外键
 76 
 77     def __str__(self):
 78         return self.name
 79 
 80     class Meta:
 81         verbose_name = \'项目表\'
 82         verbose_name_plural = verbose_name
 83         db_table = \'project\'
 84         ordering = [\'-id\']  # 按照id倒排。
 85 
 86 
 87 class Interface(BaseModel):
 88     \'\'\'接口\'\'\'
 89     name = models.CharField(verbose_name=\'接口名称\', max_length=100, unique=True)
 90     uri = models.CharField(verbose_name=\'接口路径\', max_length=1024)
 91     params = models.CharField(verbose_name=\'默认参数\', max_length=2048,null=True,blank=True)
 92     headers = models.CharField(verbose_name=\'默认Headers\', max_length=2048,null=True,blank=True)
 93     user = models.ForeignKey(User, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'创建者\')
 94     project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'归属项目\')
 95 
 96     def __str__(self):
 97         return self.name
 98 
 99     class Meta:
100         verbose_name = \'接口表\'
101         verbose_name_plural = verbose_name
102         db_table = \'interface\'
103         ordering = [\'-id\']  # 按照id倒排。
104 
105 
106 class Case(BaseModel):
107     \'\'\'用例表\'\'\'
108     title = models.CharField(verbose_name=\'用例标题\', max_length=100)
109     project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'归属项目\')
110     interface = models.ForeignKey(Interface, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'接口\')
111     user = models.ForeignKey(User, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'创建用户\')
112     method_choice = (
113         (1, \'POST\'),
114         (2, \'GET\'),
115         (3, \'DELETE\'),
116         (4, \'PUT\'),
117     )
118     method = models.SmallIntegerField(choices=method_choice, verbose_name=\'请求方式\')
119 
120     cache_field = models.CharField(verbose_name=\'缓存字段\', max_length=128, null=True, blank=True)#null=True,可能为空 blank=True 可能不传
121 
122     check = models.CharField(verbose_name=\'校验点\', max_length=512)
123     params = models.CharField(verbose_name=\'请求参数\', max_length=2048, null=True, blank=True)
124     headers = models.CharField(verbose_name=\'请求头信息\', max_length=2048, null=True, blank=True)
125     is_json = models.BooleanField(verbose_name=\'参数是否是json\', default=False)
126     json = models.CharField(verbose_name=\'json类型参数\', max_length=2048, null=True, blank=True)
127     status_choice = (
128         (1, \'通过\'),
129         (2, \'未运行\'),
130         (3, \'运行中\'),
131         (999, \'失败\')
132     )
133     status = models.SmallIntegerField(choices=status_choice, verbose_name=\'用例状态\',
134                                       default=2)  # 记录上一次的状态 每次执行后需要更新下这个表的这个字段
135     report_batch = models.CharField(verbose_name=\'最后一次执行的批次号\', null=True, max_length=512, blank=True)
136     def __str__(self):
137         return self.name
138 
139     class Meta:
140         verbose_name = \'用例表\'
141         verbose_name_plural = verbose_name
142         db_table = \'case\'
143         ordering = [\'-id\']  # 按照id倒排
144 
145 
146 class CaseCollection(BaseModel):
147     \'\'\'用例集合\'\'\'
148     name = models.CharField(verbose_name=\'集合名\', max_length=100, unique=True)
149     desc = models.CharField(verbose_name=\'描述\', max_length=200, null=True)
150     user = models.ForeignKey(User, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'创建者\')
151     project = models.ForeignKey(Project, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'归属项目\')
152     report_batch = models.CharField(verbose_name=\'最后一次执行的批次号\', null=True, max_length=512, blank=True)
153     status_choice = (
154         (2, \'未运行\'),
155         (3, \'运行中\'),
156         (4, \'执行完毕\')
157     )
158     status = models.SmallIntegerField(choices=status_choice, verbose_name=\'用例状态\',
159                                       default=2)
160     case = models.ManyToManyField(Case,verbose_name=\'集合下的用例\')
161 
162 
163     def __str__(self):
164         return self.name
165 
166     class Meta:
167         verbose_name = \'用例集合表\'
168         verbose_name_plural = verbose_name
169         db_table = \'case_collection\'
170         ordering = [\'-id\']  # 按照id倒排
171 class Report(BaseModel):
172     \'\'\'用例报告表\'\'\'
173     url = models.CharField(verbose_name=\'请求URL\', max_length=1024)
174     project = models.ForeignKey(Project, verbose_name=\'项目\', on_delete=models.DO_NOTHING, db_constraint=False)
175     title = models.CharField(verbose_name=\'用例名称\', max_length=100)
176     params = models.CharField(verbose_name=\'请求参数\', max_length=2048)
177     response = models.CharField(verbose_name=\'接口返回值结果\', max_length=2048)
178     case = models.ForeignKey(Case, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'结果所属用例\')
179     case_collection = models.ForeignKey(CaseCollection, on_delete=models.DO_NOTHING, db_constraint=False,
180                                         verbose_name=\'结果所属集合\', null=True)
181     batch = models.CharField(verbose_name=\'批次\', null=True, max_length=128)  # 用于区分运行的第几批集合的用例
182     reason = models.CharField(verbose_name=\'失败原因\', null=True, max_length=128, blank=True)
183     status_choice = (
184         (1, \'通过\'),
185         (999, \'失败\')
186     )
187     duration = models.IntegerField(verbose_name=\'用例耗时\')
188     status = models.SmallIntegerField(choices=status_choice, verbose_name=\'用例结果状态\')
189     user = models.ForeignKey(User, on_delete=models.DO_NOTHING, db_constraint=False, verbose_name=\'运行用户\')
190 
191     class Meta:
192         verbose_name = \'用例报告表\'
193         verbose_name_plural = verbose_name
194         db_table = \'report\'
195         ordering = [\'-id\']
196 class CasePremise(BaseModel):
197     \'\'\'依赖用例的关系表\'\'\'
198     case = models.ForeignKey(Case, verbose_name=\'用例id\', on_delete=models.DO_NOTHING, db_constraint=False, unique=False,related_name=\'case\')
199     premise_case = models.ForeignKey(Case, verbose_name=\'被依赖用例的id\', on_delete=models.DO_NOTHING, db_constraint=False,
200                                      unique=False,related_name=\'premise_case\')
201 
202     def __str__(self):
203         return self.case
204 
205     class Meta:
206         unique_together = (\'case\', \'premise_case\')  # 联合主键,一个case对另外一个case只能依赖一次
207         verbose_name = \'依赖关系表\'
208         verbose_name_plural = verbose_name
209         db_table = \'case_premise\'
生成数据库:
1、makemigrations skssystem

2、migrate skssystem

3、生成结果如图:

四、数据库test——练习

  1. 在项目下创建文件model_test.py
  2. 复制如下内容到文件中model_test.py
1 import django, os
2 os.environ.setdefault(\'DJANGO_SETTINGS_MODULE\', \'earth.settings\')  # 设置django的配置文件
3 django.setup()
4 from skssystem import models

练习一、外键操作练习
  • user表增加一条内容,
  • pycharm--database 增加数据方式

然后model_test.py 内容如下

1 user_obj = models.User.objects.get(id=1)
2 data = {
3     \'name\':\'外键联系\',
4     \'desc\':\'描述\',
5     \'host\':\'http://127.0.0.1:8022\',
6     \'user\':user_obj
7 
8 }
9 models.Project.objects.create(**data)

运行后,project 表中有一条内容

练习二、正向查询
1 project_obj = models.Project.objects.get(id=1)
2 print(project_obj)#返回项目名称
3 print(project_obj.user.nick)

练习三、反向查询

1 u_obj = models.User.objects.get(id=1)
2 print(u_obj.project_set.all())
练习四、删除--现象:project 表数据被删除
1 # 外键删除
2 models.Project.objects.get(id=1).delete()
3 
4 # 反向删除
5 u_obj = models.User.objects.get(id=1)
6 u_obj.project_set.all().delete()
练习五、外键自关联
1、使用database 中使用sql语句插入数据

2、输入内容然后执行操

3、外键操作
#  外键自关联
models.CasePremise.objects.create(case_id=1,premise_case_id=2)

# 查询
case_obj = models.Case.objects.get(id=1) # 获取id为1 的用例信息

# CasePremise
# case_obj.case.all() ==  select * from CasePremise where case_id= 1;
qs = case_obj.case.all() # all() 返回的是一个列表的qs

# [case_id为1的CasePremise数据]

for item in qs: # qs实际是CasePremise的qs
    # item 是CasePremise 依赖数据的对象
    print(item.case.title)
    print(item.premise_case.id)

多对多
 1 # INSERT INTO `case_collection`(`id`, `is_delete`, `create_time`, `update_time`, `name`, `desc`, `report_batch`, `status`, `project_id`, `user_id`) VALUES (1, 1, \'2020-02-12 22:08:04.594509\', \'2020-02-12 22:08:04.594617\', \'测试平台回归\', \'登录和项目的回归\', \'b4a64581-5805-49d5-8991-20c34656e07b\', 4, 1, 2);
 2 # 用例集合和用例是多对多的关系
 3 # A集合和B集合
 4 # A用例和B用例
 5 # A集合-- A用例和B用例
 6 # B集合-- A用例和B用例
 7 case_obj_A = models.Case.objects.get(id=1)#用例A
 8 case_obj_B = models.Case.objects.get(id=2)#用例B
 9 coll_obj_A=models.CaseCollection.objects.get(id=1)#集合A
10 print(case_obj_A,case_obj_B,coll_obj_A)
11 #通过集合中case字段创建多对多的创建
12 coll_obj_A.case.add(case_obj_A)#通过add()方法,创建多对多的映射关系
13 coll_obj_A.case.add(case_obj_B)
14 coll_obj=models.CaseCollection.objects.get(id=1)#集合A
15 coll_obj.case.add(1)#创建时通过id 的方式也可以
****case_collection_case 表格中会出现两条数据

多对多创建
1 case_obj_A = models.Case.objects.get(id=1) # 获取用例A
2 case_obj_B = models.Case.objects.get(id=2) # 获取用例B
3 coll_obj = models.CaseCollection.objects.get(id=1) # 获取集合
4 coll_obj.case.add(case_obj_B) # 通过add方法 创建多对多映射关系
5 coll_obj.case.add(case_obj_A) # 通过add方法 创建多对多映射关系
6 coll_obj.case.add(1) # 创建时 通过id创建 也可以

 


多对多--查询
1 case_obj_A = models.Case.objects.get(id=1) # 获取用例A
2 case_obj_B = models.Case.objects.get(id=2) # 获取用例B
3 coll_obj = models.CaseCollection.objects.get(id=1) # 获取集合
4 print(\'正向查询\',case_obj_A.case.all())
5 print(\'反向查询\',case_obj_A.casecollection_set.all())
删除--多对多的关系
1 case_obj_A = models.Case.objects.get(id=1) # 获取用例A
2 case_obj_B = models.Case.objects.get(id=2) # 获取用例B
3 coll_obj = models.CaseCollection.objects.get(id=1) # 获取集合
4 coll_obj.case.clear()  # 清除掉所有和集合有关的用例关系
5 coll_obj.case.remove(1) # 通过用例id 进行删除
6 coll_obj.case.remove(case_obj_B) # 通过用例id 进行删除

更新--多对多




1 case_obj_A = models.Case.objects.get(id=1) # 获取用例A
2 case_obj_B = models.Case.objects.get(id=2) # 获取用例B
3 coll_obj = models.CaseCollection.objects.get(id=1) # 获取集合
4 coll_obj.case.set([2])  # 将用例id为1和2的和集合建立关系
五、接口开发--登录--退出登录--全局参数
1、将example/view.py 的login 复制到sksystems/views.py 下,并将导入的内容都复制
 1 import time, django_redis,pickle
 2 from django.views import View
 3 from utils.custom_views import NbView, BaseView, PostView, GetView
 4 from utils.tools import model_to_dict
 5 from . import models, forms
 6 from utils import const
 7 from utils.custom_response import NbResponse
 8 from utils.tools import md5
 9 import json
10 
11 class LoginView(View):
12     \'\'\'登录\'\'\'
13     def post(self, request):
14         user_form_obj = forms.LoginForm(request.POST)
15         if user_form_obj.is_valid():
16             user = user_form_obj.cleaned_data[\'user\']
17             token = \'%s%s\' % (user.username, time.time())
18             token = md5(token)
19             try:
20                 redis = django_redis.get_redis_connection()
21             except:
22                 raise Exception("连接不上redis,请检查redis!")
23             redis.set(const.token_prefix+token, pickle.dumps(user), const.token_expire)
24             return NbResponse(token=token, user=user.username)
25         else:
26             return NbResponse(-1, user_form_obj.error_format)
2、sksystem/urls.py 增加登录接口的路径
1 from django.urls import path
2 from . import views
3 urlpatterns = [
4     path(\'login\', views.LoginView.as_view()),#登录
5 ]
3、sksystem 目录下创建forms.py,将exampl/forms.py的登录的内容复制到sksystem/forms.py
 1 from django.core.exceptions import ValidationError
 2 from django.db.models import Q
 3 from django.forms import ModelForm, Form
 4 from django import forms
 5 
 6 from . import models
 7 from utils.tools import ExtendForm
 8 
 9 class LoginForm(Form, ExtendForm):
10     username = forms.CharField(min_length=5, max_length=20, required=True)
11     password = forms.CharField(min_length=6, max_length=20, required=True)
12 
13     def clean(self):
14         if not self.errors:  # 校验errors里面是否有错误
15             username = self.cleaned_data[\'username\']
16             password = self.cleaned_data[\'password\']
17             user = models.User.objects.filter(Q(phone=username) | Q(email=username))
18             if user:
19                 user = user.first()
20                 if user.check_password(password):
21                     self.cleaned_data[\'user\'] = user
22                     return self.cleaned_data
23                 else:
24                     self.add_error(\'password\',\'密码错误\')
25 
26             else:
27                 self.add_error(\'username\', \'用户不存在\')
4、修改settings.py下的redis的ip和密码

  •  请求接口的过程

(1)earth/urls.py 也就是api

  (2)sksystem/urls.py 也就是login

  (3)sksystem/views.py loginview

5、用postman 请求接口

 

 退出接口

(1)sksystem/views.py

1 class LogoutView(View):
2     \'\'\'退出\'\'\'
3     def post(self, request):
4         redis = django_redis.get_redis_connection()
5         redis.delete(const.token_prefix+request.META.get(\'HTTP_TOKEN\'))
6         return NbResponse()

  (2)sksystem/urls.py

1 path(\'logout\', views.LogoutView.as_view()),#

(3)postman接口

 全局参数接口

 

(1)sksystem/views.py

1 1 # 全局参数的接口。
2 2 class ParameterView(NbView):
3 3     search_field = ["name"]  # 根据哪些字段来搜索
4 4     filter_field = []  # 根据哪些字段来搜索
5 5     model_class = models.Parameter  # 用哪个model类
6 6     form_class = forms.ParameterForm  # 用哪个form类

 

(3)sksystem/forms.py

1 class ParameterForm(ModelForm, ExtendForm):
2     class Meta:
3         model = models.Parameter
4         exclude = [\'is_delete\']

 

(4)sksystem/urls.py

1 path(\'parameter\', views.ParameterView.as_view()),#全局操作

 

  (5)postman

 

 






分类:

技术点:

相关文章:

  • 2022-01-14
  • 2019-12-22
  • 2019-01-28
  • 2021-11-07
  • 2021-11-07
  • 2021-12-03
  • 2021-05-16
猜你喜欢
  • 2022-01-14
  • 2021-12-05
  • 2021-10-26
  • 2021-11-03
  • 2021-11-15
  • 2021-07-20
  • 2021-10-16
相关资源
相似解决方案