gitpython模块

能够python代码操作git仓库

安装

pip3 install gitpython#好用的模块:pandas numpy 处理excel表格 openpyxl...

基本使用

importosfrom git.repo importRepo#下载远程仓库的代码可以怎么搞 clone pull#先定义代码的存放位置
download_path = os.path.join('jason','NB')
Repo.clone_from('https://github.com/DominicJi/TeachTest.git',to_path=download_path,branch='master') #默认branch为master

更多操作

############### 2. pull最新代码 ##############
importosfrom git.repo importRepo
local_path= os.path.join('jason', 'NB')
repo=Repo(local_path)
repo.git.pull()############### 3. 获取所有分支 ##############
importosfrom git.repo importRepo
local_path= os.path.join('jason', 'NB')
repo=Repo(local_path)
branches=repo.remote().refsfor item inbranches:print(item.remote_head)############### 4. 获取所有版本 ##############
importosfrom git.repo importRepo
local_path= os.path.join('jason', 'NB')
repo=Repo(local_path)for tag inrepo.tags:print(tag.name)############### 5. 获取所有commit ##############
importosfrom git.repo importRepo
local_path= os.path.join('jason', 'NB')

repo=Repo(local_path)#将所有提交记录结果格式成json格式字符串 方便后续反序列化操作

commit_log = repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}', max_count=50,
date='format:%Y-%m-%d %H:%M')
log_list= commit_log.split("\n")
real_log_list= [eval(item) for item inlog_list]print(real_log_list)############### 6. 切换分支 ##############
importosfrom git.repo importRepo
local_path= os.path.join('jason', 'NB')
repo=Repo(local_path)
before=repo.git.branch()print(before)
repo.git.checkout('master')
after=repo.git.branch()print(after)
repo.git.reset('--hard', '854ead2e82dc73b634cbd5afcf1414f5b30e94a8')############### 7. 打包代码 ##############
with open(os.path.join('jason', 'NB.tar'), 'wb') as fp:
repo.archive(fp)

对模块的诸多功能进行一个封装

importosfrom git.repo importRepofrom git.repo.fun importis_git_dirclassGitRepository(object):"""git仓库管理"""
def __init__(self, local_path, repo_url, branch='master'):
self.local_path= local_path #管理本地哪个文件夹
self.repo_url = repo_url #远程仓库地址
self.repo =None
self.initial(repo_url, branch)#初始化git仓库
definitial(self, repo_url, branch):"""初始化git仓库
:param repo_url:
:param branch:
:return:"""
if notos.path.exists(self.local_path):#mkdir不能创建多级目录 makedirs可以创建多级目录
os.makedirs(self.local_path)
git_local_path= os.path.join(self.local_path, '.git')if notis_git_dir(git_local_path):
self.repo= Repo.clone_from(repo_url, to_path=self.local_path, branch=branch)else:
self.repo=Repo(self.local_path)defpull(self):"""从线上拉最新代码
:return:"""self.repo.git.pull()defbranches(self):"""获取所有分支
:return:"""branches=self.repo.remote().refsreturn [item.remote_head for item in branches if item.remote_head not in ['HEAD', ]]defcommits(self):"""获取所有提交记录
:return:"""commit_log= self.repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}',
max_count=50,
date='format:%Y-%m-%d %H:%M')
log_list= commit_log.split("\n")return [eval(item) for item inlog_list]def tags(self): #版本(github网页在branch旁边)
"""获取所有tag
:return:"""
return [tag.name for tag inself.repo.tags]defchange_to_branch(self, branch):"""切换分值
:param branch:
:return:"""self.repo.git.checkout(branch)defchange_to_commit(self, branch, commit):"""切换commit
:param branch:
:param commit:
:return:"""self.change_to_branch(branch=branch)
self.repo.git.reset('--hard', commit)defchange_to_tag(self, tag):"""切换tag
:param tag:
:return:"""self.repo.git.checkout(tag)#使用
if __name__ == '__main__':
local_path= os.path.join('codes', 'luffycity')
repo=GitRepository(local_path,remote_path)
branch_list=repo.branches()print(branch_list)
repo.change_to_branch('dev')
repo.pull()

代码发布概述图


s:当服务器特别多的时候,从同一个地方下载数据回出现压力过大的情况(上传者只有一个,下载者有N多个,上传者压力太大)

如何解决这种问题???

比特流技术

将所有人都变成既可以是上传者也可以是下载者

联想你下载小片片的时候有些速度快游戏速度慢,速度快可能是因为你室友的电脑中就有,你是从你室友的电脑中下载的,速度慢是因为你的周围都没有该资源的提供者

项目编写

服务器管理

classServer(models.Model):"""服务器表"""hostname= models.CharField(verbose_name='主机名',max_length=64)

利用modelform实现服务器表的增删改查

所有的项目大部分的功能都是由最简单的增删改查组成,是整个业务逻辑的基础

并且只需要认认真真的写一个增删改查即可,后续所有的直接CV大法完事!!!

模版的基础作为模版的html文件上一般情况下,都应该定义三个区域cs区,html

内容区,js区

针对服务器添加数据的功能,需要对提交的数据进行数据校验,还需要展示提示信息

当模型字段非常多的时候前端页面展示代码量书写非常多

如何解决上述问题

"""标签渲染

数据校验

信息展示

forms组件的功能

modelform组件也可以完成上面的三个要求,并且功能更加的强大简单"""

classServerModelForm(ModelForm):classMeta:
model=models.Server
fields= "__all__" # 所有字段
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)#print(self.fields) # OrderedDict([('hostname', )])
#给所有的字段加class属性
for k,field_obj inself.fields.items():
field_obj.widget.attrs['class'] = 'form-control'
return redirect('/server/list/') #可以写路径
return redirect('server_list') #还可以写别名 但是如果出现有名无名分组的反响解析 则必须使用reverse方法

语言环境

django默认的语言环境是英文,但是它的内部其实支持多个国家的语言,只需要你自己手动配置即可

#LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'
#如何查看django到底支持哪些语言环境
from django.conf importglobal_settings
LANGUAGES=[
('af', gettext_noop('Afrikaans')),
('ar', gettext_noop('Arabic')),
('ast', gettext_noop('Asturian')),
...
]

针对删除功能,我们想做一个二次确认的过程(ajax结合sweetalert实现二次确认弹框)

{% block content %}

项目列表

添加数据

ID项目名仓库地址环境线上地址关联服务器操作

{% for project_obj in project_queryset %}{{ project_obj.pk }}{{ project_obj.title }}{{ project_obj.repo }}{{ project_obj.get_env_display }}{{ project_obj.path }}{% for server_obj in project_obj.servers.all %}{{ server_obj.hostname }}{% endfor %}


编辑

删除{# this是自带,指代当前被操作对象 #}

{% endfor %} 
 
{% endblock %}
{% block js %}
functionremoveData(ths,sid) {varres=confirm('你缺点要删除吗?');
{#alert(res)//布尔值#}
if(res){//朝后端发送删除数据的请求
$.ajax({
url:'/server/delete/' +sid+ '/',
type:'get',
success:function(args) {//删除成功之后 页面应该立刻展示删除之后的效果
//1 直接刷新 不太好 设计到分页的情况不太好
{#window.location.reload()#}if(args.status){//2 利用DOM操作实时删除
$(ths).parent().parent().remove()
}
}
})
}
}

项目管理

classProject(models.Model):"""项目表"""title= models.CharField(verbose_name='项目名',max_length=64)
repo= models.CharField(verbose_name='仓库地址',max_length=128)
env_choices=(
('prod','正式'),
('test','测试')
)
env= models.CharField(verbose_name='环境',max_length=16,choices=env_choices,default='test')

直接搬砖操作,CV搞定

代码的优化

代码的优化一定是在你把功能实现之后再去优化(先努力实现再考虑优化)

将所有的modelform单独抽取出来

将modelform类中所有公共的部分抽取出来形成基类

"""什么是类?

类是对象公共的属性和技能的结合体

什么是父类?

父类是类公共的属性和技能的结合体"""

#父类
from django.forms importModelFormclassBaseModelForm(ModelForm):def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)#print(self.fields) # OrderedDict([('hostname', )])
#给所有的字段加class属性
for k,field_obj inself.fields.items():
field_obj.widget.attrs['class'] = 'form-control'
#子类
from app01.myforms.base importBaseModelFormfrom app01 importmodelsclassServerModelForm(BaseModelForm):classMeta:
model=models.Server
fields= "__all__"

当模型表字段特别多的时候,并且并不是所有的字段都需要展示到前端给用户观看

from django.forms importModelFormclassBaseModelForm(ModelForm):#自定义字段是否需要加额外属性的配置
exclude_bootstrap =[]def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)#print(self.fields) # OrderedDict([('hostname', )])
#给所有的字段加class属性
for k,field_obj inself.fields.items():if k inself.exclude_bootstrap:continue #排除在外不添加样式
field_obj.widget.attrs['class'] = 'form-control'
项目表需要额外添加字段
#线上服务器地址
path = models.CharField(verbose_name='线上地址',max_length=64)#关联服务器

"""一个项目可以跑在多个服务器上

一个服务器其实也可以跑多个项目 (公司服务器不够的时候 可以混用)"""servers= models.ManyToManyField(to='Server',verbose_name='关联服务器')

项目展示页面额外展示当前两个字段

ModelForm使用
from django.forms importModelFormclassBaseModelForm(ModelForm):classMeta:
model=models.Userinfo
fields= '__all__'
#exclude = ['uid'] # 排除在外
#展示标签
form_obj =BaseModelForm()#校验数据
form_obj = BaseModelForm(data=request.POST)
form_obj.is_valid()#新增数据
form_obj.save()#展示待编辑数据
form_obj = BaseModelForm(instance=edit_obj)#编辑数据
form_obj = BaseModelForm(data=request.POST,instance=edit_obj)
form_obj.is_valid()
form_obj.save()"""新增和编辑调用的都是save方法,两者通过instance来区分"""

项目示例


#s13_deploy/app01/myforms/base.py
from django.forms importModelFormclassBaseModelForm(ModelForm):def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)for k,field_obj inself.fields.items():
field_obj.widget.attrs['class'] = 'form-control'
#s13/_eploy/app01/myforms/server.py
from app01.myforms.base importBaseModelFormfrom app01 importmodelsclassServerModelForm(BaseModelForm):#exclude_bootstrap = ['hostname']
classMeta:
model=models.Server
fields= '__all__' #所有字段
#s13_deploy/app01/templates/form.html
{% extends 'base.html' %}
{% block content %}
 {#点击按钮为post请求 novalidate禁止前端渲染提示 #} 
 
{% csrf_token %}
{% for foo in form_obj %}
 
 
{{ foo.label }} {#label为verbose_name #}
 
  
{{ foo.errors.0}}
{% endfor %} 
 
提交
{% endblock %}#s13_deploy/app01/views/server.py#服务器相关逻辑 
 
from django.shortcuts importHttpResponse,render,redirectfrom app01 importmodelsfrom django.http importJsonResponsefrom app01.myforms.server importServerModelFormdefserver_add(request):#1 先生成一个modelform的空对象
form_obj =ServerModelForm()if request.method == 'POST':#3 检验数据
form_obj = ServerModelForm(data=request.POST)#判断是否合法
ifform_obj.is_valid():#保存诗句
form_obj.save()#跳转到服务器的展示页
#return redirect('/server/list/') # 可以写路径
return redirect('server_list') #可以写别名
#2 将该对象传给html文件
return render(request,'form.html',locals())defserver_edit(request,edit_id):
edit_obj= models.Server.objects.filter(pk=edit_id).first()#1 生成待编辑的modelform对象
form_obj = ServerModelForm(instance=edit_obj)if request.method == 'POST': #编辑操作 如何区分编辑还是新增就看有没有instance参数
form_obj = ServerModelForm(data=request.POST,instance=edit_obj) #必须加instance,否则为新增
ifform_obj.is_valid():
form_obj.save()return redirect('server_list')return render(request,'form.html',locals())#s13/deploy/app01/models.py
from django.db importmodelsclassServer(models.Model):#服务器表
hostname = models.CharField(verbose_name='主机名',max_length=64)#s13_deploy/s13_deploy/urls.pyfrom django.urls importpath,re_pathfrom app01.views importserver,project
urlpatterns=[#服务器相关url
path('server/list/', server.server_list,name='server_list'),
path('server/add/', server.server_add,name='server_add'),
re_path('server/edit/(?P\d+)', server.server_edit,name='server_edit'),
re_path('server/delete/(?P\d+)', server.server_delete,name='server_delete'),
]

重定向

"""redirect括号内既可以直接书写url也可以写反响解析的别名但是不能有无名和有名分组的情况,如果有则还需要借助于reverse方法"""redirect('/index/')

redirect('index')

删除二次确认及页面刷新

二次确认你可以直接使用原生的BOM操作,也可以借助于第三方插件是页面更加的好看,针对删除之后页面的刷新,最好不要直接刷新因为那样没有考虑到分页的情况,简易你使用DOM操作的方式刷新页面,能够保证在分页的情况下也能合理展示

代码优化

"""1.将项目中所使用到的modelform单独存储

2.整合所有modelform相同的代码 抽成基类

3.在modelform中自定义一个控制字段是否需要加bootstrap样式的功能

4.项目表新增远程服务器地址以及关联的服务器"""