【Django】函数库【原创】.md

函数库

from django.http import JsonResponse
from django.db.models.fields import DateTimeField
from django.db.models.fields.related import ManyToManyField
import os
import signal
import subprocess
import requests
import json
import platform
import datetime
import re
import socket


def render_json(code=0, msg='success', data={}):
    result = {
        'code': code,
        'message': msg,
        'data': data,
    }
    return JsonResponse(result)


def is_ip(address):
    """
    校验是否是IP地址
    :param address:
    :return:
    """
    compile_ip = re.compile(
        '^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$')
    if compile_ip.match(address):
        return True
    else:
        return False


def get_ip(request):
    """
    获取IP
    :param request:
    :return:
    """
    x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')

    x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
    if x_real_ip:
        ip = x_real_ip
    elif x_forwarded_for:
        ip = x_forwarded_for.split(',')[0]
    else:
        ip = request.META.get('REMOTE_ADDR')
    return ip


def get_ips_list(ips):
    """
    根据正则表达式获取字符串中的IP地址
    """
    pattern = re.compile(
        r"((?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))))")
    a = pattern.findall(ips)
    ips_list = [g[0] for g in a]

    return ips_list


def get_request(url, params={}, headers={}, timeout=120):
    """
    HTTP请求-Get请求
    :param url:
    :param params:  string URL中的参数
    :param headers:
    :param timeout:
    :return:
    """
    if not headers:
        headers = {
            "Content-Type": "application/json",
        }

    response = requests.request('GET', url, headers=headers, params=params, timeout=timeout)
    return response.text


def post_request(url, params={}, data={}, headers={}, timeout=120):
    """
    HTTP请求-Post请求
    :param url:
    :param params:  string URL中的参数
    :param data:    dict body中的参数
    :param headers: dict
    :param timeout:
    :return:
    """
    if not headers:
        headers = {
            "Content-Type": "application/json",
        }

    response = requests.request('POST', url, headers=headers, params=params, data=json.dumps(data), timeout=timeout)
    return response.text


def run_cmd(cmd_string, timeout=600):
    """
    执行命令
    :param cmd_string:  string 字符串
    :param timeout:  int 超时设置
    :return:
    """
    p = subprocess.Popen(cmd_string, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True, close_fds=True,
                         start_new_session=True)

    format = 'utf-8'
    if platform.system() == "Windows":
        format = 'gbk'

    try:
        (msg, errs) = p.communicate(timeout=timeout)
        ret_code = p.poll()
        if ret_code:
            code = 1
            msg = "[Error]Called Error : " + str(msg.decode(format))
        else:
            code = 0
            msg = str(msg.decode(format))
    except subprocess.TimeoutExpired:
        # 注意:不能使用p.kill和p.terminate,无法杀干净所有的子进程,需要使用os.killpg
        p.kill()
        p.terminate()
        # 不要使用signal.SIGUSR1,这个是自定义的用户信号,signal.SIGTERM这个相当于kill命令
        # os.killpg(p.pid, signal.SIGUSR1)
        os.killpg(p.pid, signal.SIGTERM)

        # 注意:如果开启下面这两行的话,会等到执行完成才报超时错误,但是可以输出执行结果
        # (outs, errs) = p.communicate()
        # print(outs.decode('utf-8'))

        code = 1
        msg = "[ERROR]Timeout Error : Command '" + cmd_string + "' timed out after " + str(timeout) + " seconds"
    except Exception as e:
        code = 1
        msg = "[ERROR]Unknown Error : " + str(e)

    return code, msg


def get_uuid():
    """
    生成唯一的uuid
    :return:
    """
    import uuid
    uid = str(uuid.uuid4())
    return ''.join(uid.split('-'))


def UTC2Local(utc_str):
    """
    处理UTC时间
        类似:2019-10-23T06:00:34.882747 或者是  2020-01-13T19:53:56Z时间
    :param utc_str
    :return:
    """
    # 先去掉小数点
    utc_str = utc_str.split('.')[0]

    # 第一次替换为空格,第二次替换为空字符串
    utc_time = utc_str.replace("T", " ").replace("Z", "")

    # UTC转本地时间+8h
    utc_str = datetime.datetime.strptime(utc_time, "%Y-%m-%d %H:%M:%S") + datetime.timedelta(hours=8)

    # 控制输出格式
    return utc_str.strftime("%Y-%m-%d %H:%M:%S")


def validate_password(password, min_len=8, max_len=26):
    """
    校验密码
        长度:8-26位
        密码至少包含:大写字母、小写字母、数字、特殊字符(!@$%^-_=+[{}]:,./?)中的三种
    :param max_len:
    :param min_len:
    :param password:
    :return:
    """
    length = len(password)
    if length < min_len:
        return 200, '密码长度不符'

    if length > max_len:
        return 200, '密码长度不符'

    reg = "[A-Za-z0-9!@$%^-_=+\[{}\]:,./?]"
    if len(re.findall(reg, password)) < length:
        return 201, '密码有非法字符'

    first = re.search('[A-Z]', password)
    num1 = 1 if first else 0

    second = re.search('[a-z]', password)
    num2 = 1 if second else 0

    third = re.search('[0-9]', password)
    num3 = 1 if third else 0

    fourth = re.search("[!@$%^-_=+\[{}\]:,./?]", password)
    num4 = 1 if fourth else 0

    if num1 + num2 + num3 + num4 < 3:
        return 202, '密码必须包含大写字母、小写字母、数字和特殊字符中的三种'

    return 0, 'success'


def is_dir(path):
    """
    判断目录是否存在
    :param path:
    :return:
    """
    if path and os.path.isdir(path):
        return True

    return False


def is_file(path):
    """
    判断文件是否存在
    :param path:
    :return:
    """
    if path and os.path.isfile(path):
        return True

    return False


def traverse_path(path):
    """
    遍历目录,获取文件和目录
    :param path:
    :return:
    """
    g = os.walk(path)

    dirs = []
    files = []

    # 三个参数:分别返回 1.父目录 2.所有文件夹名字(不含路径) 3.所有文件名字
    for path, dir_list, file_list in g:
        for dir_name in dir_list:
            dirs.append(os.path.join(path, dir_name))

        for file_name in file_list:
            files.append(os.path.join(path, file_name))

    return dirs, files


def get_file_type(file):
    """
    获取文件的后缀名
    :param file:
    :return:
    """
    if not file:
        return ''

    file_list = os.path.splitext(file)

    if len(file_list) >= 2:
        return file_list[1]

    return ''


def get_ips(cidr):
    """
    获取某个网段的所有IP
    注意:需要安装IPy,pip install IPy
    :param cidr:
    :return:
    """
    from IPy import IP
    ips = IP(cidr)
    return ips


def get_next_value(value, list):
    """
    获取list中value的下一个值(如果value为最后一个,则下一个为第一个)
    :param value:
    :param list:
    :return:
    """
    if value not in list:
        return ''

    list_count = len(list)
    index = list.index(value)

    next_index = index + 1 if (index + 1) < list_count else 0
    return list[next_index]


def md5_string(content):
    """
    MD5加密
    :param content:
    :return:
    """
    if not content:
        return ''

    import hashlib
    return hashlib.md5(content.encode(encoding="UTF-8")).hexdigest()


def get_python_version():
    """
    获取Python版本
    :return:
    """
    import sys
    return sys.version_info


def is_json(string):
    """
    判断字符串是否是Json格式
    :param string:
    :return:
    """
    try:
        json_obj = json.loads(string)
        return True
    except ValueError as e:
        return False


def model_to_dict(obj, fields=None, exclude=None):
    """
    Model类数据转成字典
    :param obj:
    :param fields:
    :param exclude:
    :return:
    """
    data = {}
    if not obj:
        return data

    for f in obj._meta.concrete_fields + obj._meta.many_to_many:
        value = f.value_from_object(obj)

        if fields and f.name not in fields:
            continue

        if exclude and f.name in exclude:
            continue

        if isinstance(f, ManyToManyField):
            value = [i.id for i in value] if obj.pk else None

        if isinstance(f, DateTimeField):
            value = value.strftime('%Y-%m-%d %H:%M:%S') if value else None

        data[f.name] = value

    return data


def cut_list(list, num):
    """
    将一个数组平均分配为n个,每一个的个数为num
    返回的是双重数组
    比如:  ['aa', 'bb', 'cc'],切割为多个,每个的数量为2,那么返回:
    [['aa', 'bb'], ['cc']]
    :param list:
    :param num:
    :return:
    """
    res = []
    for i in range(0, len(list), num):
        res.append(list[i:i + num])

    return res


def gen_dates(b_date, days):
    day = datetime.timedelta(days=1)
    for i in range(days):
        yield b_date + day * i


def get_date_list(start, end=None, format='%Y-%m-%d'):
    """
    获取日期列表,给一个开始时间和一个结束时间(如不传则为今天),输出这两个时间中间的所有日期
    :param start: 开始日期
    :param end: 结束日期
    :param format: 返回的日期格式
    :return:
    """
    start = datetime.datetime.strptime(start, "%Y-%m-%d")

    if end:
        end = datetime.datetime.strptime(end, "%Y-%m-%d")
    else:
        end = datetime.datetime.now()

    data = []
    for d in gen_dates(start, (end - start).days):
        data.append(d.strftime(format))
    return data


def get_host_ip():
    """
    查询本机ip地址
    :return: ip
    """
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(('8.8.8.8', 80))
        ip = s.getsockname()[0]
    finally:
        s.close()

    return ip


def get_host_name():
    """
    查询本机hostname,如果是:xxx.novalocal,则只获取xxx
    """
    hostname = socket.gethostname()
    name = hostname.split('.')[0] if '.' in hostname else hostname
    return name


def string_similar(string1, string2):
    """
    返回两个字符串的相似度  比如:返回1:全相等  返回0.987等
    """
    import difflib
    return difflib.SequenceMatcher(None, string1, string2).quick_ratio()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值