代码发布3 gitpython模块, 代码发布概述图, 服务器管理, 项目管理, 发布任务管理

gitpython模块

能够python代码操作git仓库

安装

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

基本使用

import os
from git.repo import Repo

# 下载远程仓库的代码可以怎么搞   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最新代码 ##############
import os
from git.repo import Repo
 
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
repo.git.pull()

# ############## 3. 获取所有分支 ##############
import os
from git.repo import Repo
 
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
 
branches = repo.remote().refs
for item in branches:
    print(item.remote_head)
    
# ############## 4. 获取所有版本 ##############
import os
from git.repo import Repo
 
local_path = os.path.join('jason', 'NB')
repo = Repo(local_path)
 
for tag in repo.tags:
    print(tag.name)

# ############## 5. 获取所有commit ##############
import os
from git.repo import Repo
 
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 in log_list]
print(real_log_list)
 
# ############## 6. 切换分支 ##############
import os
from git.repo import Repo
 
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)

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

import os
from git.repo import Repo
from git.repo.fun import is_git_dir

class GitRepository(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仓库

    def initial(self, repo_url, branch):
        """
        初始化git仓库
        :param repo_url:
        :param branch:
        :return:
        """
        if not os.path.exists(self.local_path):
            # mkdir不能创建多级目录     makedirs可以创建多级目录
            os.makedirs(self.local_path)

        git_local_path = os.path.join(self.local_path, '.git')
        if not is_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)

    def pull(self):
        """
        从线上拉最新代码
        :return:
        """
        self.repo.git.pull()

    def branches(self):
        """
        获取所有分支
        :return:
        """
        branches = self.repo.remote().refs
        return [item.remote_head for item in branches if item.remote_head not in ['HEAD', ]]

    def commits(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 in log_list]

    def tags(self):  # 版本(github网页在branch旁边)
        """
        获取所有tag
        :return:
        """
        return [tag.name for tag in self.repo.tags]

    def change_to_branch(self, branch):
        """
        切换分值
        :param branch:
        :return:
        """
        self.repo.git.checkout(branch)

    def change_to_commit(self, branch, commit):
        """
        切换commit
        :param branch:
        :param commit:
        :return:
        """
        self.change_to_branch(branch=branch)
        self.repo.git.reset('--hard', commit)

    def change_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多个,上传者压力太大)

如何解决这种问题???

比特流技术

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

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

项目编写

服务器管理

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

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

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

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

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

内容区,js区

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

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

如何解决上述问题

"""
标签渲染
数据校验
信息展示

forms组件的功能
modelform组件也可以完成上面的三个要求,并且功能更加的强大简单
"""
class ServerModelForm(ModelForm):
    class Meta:
        model = models.Server
        fields = "__all__"


    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # print(self.fields)  # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
        # 给所有的字段加class属性
        for k,field_obj in self.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 import global_settings
LANGUAGES = [
    ('af', gettext_noop('Afrikaans')),
    ('ar', gettext_noop('Arabic')),
    ('ast', gettext_noop('Asturian')),
  ...
]

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

<script>
        function removeData(ths,sid) {
            var res = 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()
                        }
                    }
                })
            }
        }
    </script>

项目管理

class Project(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 import ModelForm


class BaseModelForm(ModelForm):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # print(self.fields)  # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
        # 给所有的字段加class属性
        for k,field_obj in self.fields.items():
            field_obj.widget.attrs['class'] = 'form-control'
            
            
            
# 子类
from app01.myforms.base import BaseModelForm
from app01 import models


class ServerModelForm(BaseModelForm):
    class Meta:
        model = models.Server
        fields = "__all__"
  • 当模型表字段特别多的时候,并且并不是所有的字段都需要展示到前端给用户观看
from django.forms import ModelForm


class BaseModelForm(ModelForm):
    # 自定义字段是否需要加额外属性的配置
    exclude_bootstrap = []

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # print(self.fields)  # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
        # 给所有的字段加class属性
        for k,field_obj in self.fields.items():
            if k in self.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='关联服务器')
  • 项目展示页面额外展示当前两个字段

猜你喜欢

转载自www.cnblogs.com/ludingchao/p/12709005.html