目录
一、数据库连接
import pymssql
# todo:连接SQL
def connect_sql(server, database, sql):
connect = pymssql.connect(server=server,
user='sa',
password='password',
port='1433',
database=database,
login_timeout=3)
cursor = connect.cursor()
cursor.execute(sql)
des = cursor.description # 显示每列的详细信息
title = [des[i][0] for i in range(len(des))]
df = pd.DataFrame(cursor.fetchall(), columns=title)
connect.close()
return df
# todo:修改数据
def change_data(server, database, sql):
connect = pymssql.connect(server=server,
user='sa',
password='password',
port='1433',
database=database,
login_timeout=3)
cursor = connect.cursor()
cursor.execute(sql)
connect.commit()
connect.close()
二、Django相关
1、session
request.session['title'] = list(df.columns)
request.session['data'] = np.array(df).tolist()
request.session.set_expiry(0) # 关闭浏览器过期
2、分页
logs = Logtext.objects.filter(user__exact=request.user.id).order_by('-date')
# dic = df.to_dict(orient='records')
p = Paginator(logs , 10, 1)
# p = Paginator(dic, 10, 1)
try:
pages = p.get_page(page)
except PageNotAnInteger:
pages = p.get_page(1)
except EmptyPage:
pages = p.get_page(p.num_pages)
3、生成Excel
def generate_excel(title, data, sheet_name, excel_name):
bio = BytesIO()
writer = pd.ExcelWriter(bio, engine='openpyxl')
df = pd.DataFrame(request.session.get('data'), columns=request.session.get('title'))
df.to_excel(writer, sheet_name='Sheet1', index=False)
writer.close()
bio.seek(0)
r = StreamingHttpResponse(bio)
r['content_type'] = 'application/octet-stream'
r['Content-Disposition'] = ('attachment;filename=期初数据.xlsx').encode(
'utf-8', 'ISO-8859-1')
r["Access-Control-Expose-Headers"] = "Content-Disposition"
return r
4、数据筛选
logs = Logtext.objects.filter(user__exact=request.user.id).order_by('-date')
from django.db.models import Q
data = Todolist.objects.filter(
Q(user__exact=request.user.id, status__exact=False) | # 未完成
Q(user__exact=request.user.id, create_time__gt=datetime.now().date(), status__exact=True) # 已完成,时间大于今天
).order_by('status', 'create_time')
5、定时任务
pip install apscheduler==2.1.2
在Django应用目录下的urls.py文件中引入这个模块和写好的想要被自动执行的函数
from apscheduler.scheduler import Scheduler
# 假设我要执行的函数时app01项目下的views.py中的func_01函数
from app_01.views import func_01
sched = Scheduler() #实例化,固定格式
# 装饰器,seconds=60意思为该函数为1分钟运行一次
@sched.interval_schedule(seconds=60)
def mytask():
func_01()
# 装饰器,意思为该函数为每天15:05:00运行一次
@sched.cron_schedule(hour=15,minute=5)
def mytask():
test_ap()
"""
hour =19 , minute =23
hour ='19', minute ='23'
minute = '*/3' 表示每 5 分钟执行一次
hour ='19-21', minute= '23' 表示 19:23、 20:23、 21:23 各执行一次任务
"""
sched.start() #启动该脚本
interval触发器
参数 | 说明 |
---|---|
weeks | 周(整形) |
days | 一个月中的第几天(整形) |
hours | 小时(整形) |
minutes | 分钟(整形) |
seconds | 秒(整形) |
start_date | 间隔触发的起始时间 |
end_date | 间隔触发的结束时间 |
jitter | 触发的时间误差 |
crontab触发器
参数 | 说明 |
---|---|
year | 4位数字的年份 |
month | 1-12月份 |
day | 1-31日 |
week | 1-53周 |
day_of_week | 一个礼拜中的第几天( 0-6或者 mon、 tue、 wed、 thu、 fri、 sat、 sun) |
hour | 0-23小时 |
minute | 0-59分钟 |
second | 0-59秒 |
start_date | datetime类型或者字符串类型,起始时间 |
end_date | datetime类型或者字符串类型,结束时间 |
timezone | 时区 |
jitter | 任务触发的误差时间 |
表达式
表达式 | 字段 | 描述 |
---|---|---|
* | 任何 | 在每个值都触发 |
*/a | 任何 | 每隔 a 触发一次 |
a-b | 任何 | 在 a-b 区间内任何一个时间触发(a必须小于b) |
a-b/c | 任何 | 在 a-b 区间内每隔 c 触发一次 |
xth y | day | 在第 x 个星期 y 触发 |
lastx | day | 最后一个星期 x 触发 |
last | day | 一个月中的最后一天触发 |
x,y,z | 任何 | 可以把上面的表达式进行组合 |
三、Pandas相关
1、df转字典
==> df
A B
0 1 2
1 3 4
dict ⇒ {'A': {0: 1, 1: 3}, 'B': {0: 2, 1: 4}}
list ⇒ {'A': [1, 3], 'B': [2, 4]}
split ⇒ {'index': [0, 1], 'columns': ['A', 'B'], 'data': [[1, 2], [3, 4]]}
records ⇒ [{'A': 1, 'B': 2}, {'A': 3, 'B': 4}]
index ⇒ {0: {'A': 1, 'B': 2}, 1: {'A': 3, 'B': 4}}
dic = df[['A', 'B']].set_index('A').T.to_dict('dict')
⇒ {1: {'B': 2}, 3: {'B': 4}}
==> df
字段1 字段2
0 A a
1 B b
dic = df.set_index(['字段1'])['字段2'].to_dict()
⇒ {'A': 'a', 'B': 'b'}
2、常用语法1
# todo:从指定行开始读取excel
df = pd.read_excel(path, header=1)
# todo:指定列格式转换
df[['数量', '剩余天数']] = df[['数量', '剩余天数']].astype(float)
# todo:按列排序
df.sort_values(by='剩余天数', inplace=True)
df.sort_values(by=['A', 'B'], ascending=[False, False], inplace=True)
# todo:使用query查询
df = df.query("剩余天数>=0 & 剩余天数<=30")
# todo:数据透视
df = pd.pivot_table(df, index=['时间'], aggfunc=np.sum).reset_index()
# todo:数据筛选
df = df[df['客户名称'].isnull() == False]
df = df[df['单号'].str.contains('PXSFH')]
df = df[df['日期'].isin(date_lst)]
# todo:删除重复数据
df = df.drop_duplicates(subset=['year', 'month'], keep='first')
"""
当keep=False时,就是去掉所有的重复行
当keep='first'时,就是保留第一次出现的重复行
当keep='last'时就是保留最后一次出现的重复行。
"""
# todo:查找重复行
df = df[df.duplicated(subset=["C"],keep=False)]
# todo:数据拼接(上下)
df = pd.concat([df1, df2, df3], axis=0, ignore_index=True)
# todo:保留小数
df = df.round({'amount': 2})
# todo:数据拼接(左右)
df = pd.merge(df1, df2, left_on=['日期'], right_on=['日期'], how='outer')
# todo:数据计算
df.eval("审核时间差=审核时间-制单时间", inplace=True)
# todo:获取工作日日期列表
date_lst = pd.bdate_range(date_start, date_end).date
# todo:时间处理
df['时间差'] = df['时间差'].astype('timedelta64[s]').astype(float)
# todo:向上填充
df[['A', 'B']] = df[['A', 'B']].fillna(method='ffill')
# todo:数据替换
df['型号'].replace({'a': 'b'}, inplace=True)
# todo:使用正则表达式替换
df['单位'] = df['单位'].str.replace('\(.*\)', '', regex=True)
df['库位名称'].replace('.*-', '', regex=True, inplace=True)
# todo:根据一列的值修改另一列的值
df.loc[df['唯一码'].isnull() == False, '数量'] = 1
# todo:新增一行合计
df.loc['new'] = ['合计', df['未开票金额'].sum()]
# todo:object与datetime64[ns]互转
df['A'] = pd.to_datetime(df['A'], format ='%Y-%m-%d') # object转datetime64[ns]
df['A'] =df['A'].apply(lambda x: x.strftime('%Y-%m-%d')) # datetime64[ns]转object
# todo:多个df进行merge
import pandas as pd
from functools import reduce
dfs = [df1, df2, df3, df4]
df_final = reduce(lambda left, right: pd.merge(left, right, on='列名', how='outer'), dfs)
# todo:数据炸开和合并
df = df.explode(column='C', ignore_index=True)
df = df.groupby(['A','B'])['C'].apply(list).to_frame().reset_index()
3、常用语法2
df["Age"].max()
df.describe() # 数据表数值数据的一些基本统计数据
titanic.head(8) # 前8排数据帧
titanic.tail(10) # DataFrame的最后10行
titanic.dtypes # 解释每一列数据类型
titanic.info() # 更详细地解释输出
df.shape # 行数和列数
# mean()平均值 median()中位数 max()最大值 min()最小值 sum()求和 std()标准差
titanic[["Age", "Fare"]].mean() # 平均年龄和票价
titanic[["Sex", "Age"]].groupby("Sex").mean() # 男性与女性的平均年龄
titanic.groupby("Sex")["Age"].mean() # 男性与女性的平均年龄
titanic.groupby(["Sex", "Pclass"])["Fare"].mean() # 每种性别和舱位组合的平均票价
titanic["Pclass"].value_counts() # 每个客舱的乘客人数是多少(value_counts()方法计算列中每个类别的记录数)
titanic.sort_values(by=['Pclass', 'Age'], ascending=False) # 按船舱等级和船龄按降序排序
# todo:数据筛选
titanic[["Age", "Sex"]]
titanic[titanic["Age"] > 35]
titanic[titanic["Pclass"].isin([2, 3])]
titanic[(titanic["Pclass"] == 2) | (titanic["Pclass"] == 3)]
titanic[titanic["Age"].notna()]
titanic.loc[titanic["Age"] > 35, "Name"]
titanic.iloc[9:25, 2:5]
四、html相关
1、漂浮文字js
<!-- 漂浮文字-->
<script type="text/javascript">
var a_idx = 0;
jQuery(document).ready(function ($) {
$("body").click(function (e) {
var a = ["诚信", "责任", "协作", "创新"];
var $i = $("<span />").text(a[a_idx]);
a_idx = (a_idx + 1) % a.length;
var x = e.pageX,
y = e.pageY;
$i.css({
"z-index": 999999999999999999999999999999999999999999999999999999,
"top": y - 20,
"left": x,
"position": "absolute",
"font-weight": "bold",
"color": "#5873FE"
});
$("body").append($i);
$i.animate({
"top": y - 90,
"opacity": 0
},
1500,
function () {
$i.remove();
});
});
});
</script>
2、下拉框改变触发ajax
if request.is_ajax():
if 'name' in request.POST:
name = request.POST['name']
df = pd.DataFrame(Relation.objects.filter(name__exact=name).values('company', 'number', 'bank'))
company_lst = list(set(np.array(df['company']).tolist()))
company_lst.sort()
number_lst = list(set(np.array(df['number']).tolist()))
number_lst.sort()
bank_lst = list(set(np.array(df['bank']).tolist()))
bank_lst.sort()
return JsonResponse({"company": company_lst, 'number': number_lst, 'bank': bank_lst})
elif 'account' in request.POST:
account = request.POST['account']
company = request.POST['company']
tip_price, tip_price_1, tip_price_2 = quota(account, company)
return JsonResponse({"tip_price": tip_price, 'tip_price_1': tip_price_1, 'tip_price_2': tip_price_2})
<script>
function change_data() {
var name = $('#select2').val();
var account = '';
$.ajax({
type: 'post',
url: '/finance/fnc_f10/-1/',
data: {
"csrfmiddlewaretoken": '{{ csrf_token }}',
"name": name,
},
}).success(function (data) {
account = data['number'][0];
$("#select1").empty();
$("#select3").empty();
$("#select4").empty();
for (var i in data['company']) {
$('#select1').append("<option value='" + data['company'][i] + "'>" + data['company'][i] + "</option>")
}
for (var i in data['number']) {
$('#select3').append("<option value='" + data['number'][i] + "'>" + data['number'][i] + "</option>")
}
for (var i in data['bank']) {
$('#select4').append("<option value='" + data['bank'][i] + "'>" + data['bank'][i] + "</option>")
}
$('#price').val('');
var company = $('#select1').val();
/*var account = $('#select3').val();*/
$.ajax({
type: 'post',
url: '/finance/fnc_f10/-1/',
data: {
"csrfmiddlewaretoken": '{{ csrf_token }}',
"account": account,
"company": company,
},
}).success(function (data) {
$('#tip_price_1').val(data['tip_price_1']);
$('#tip_price_2').val(data['tip_price_2']);
var tip_price = data['tip_price'].toString();
var result_price = $('#text_dan').val();
var min_price = 0;
if (parseFloat(tip_price) <= parseFloat(result_price)) {
min_price = tip_price
} else {
min_price = result_price
}
$('#price').attr('oninput', `if(value>${min_price})value=${min_price};if(value<0)value=0`)
});
});
}
</script>
3、数字转大写
<script>
function change() {
var price = $('#price').val();
$('#price_big').val(ToString(price));
}
function ToString(n) {
if (!/^(0|[1-9]\d*)(\.\d+)?$/.test(n)) {
return "数据非法"; //判断数据是否大于0
}
var unit = "仟佰拾亿仟佰拾万仟佰拾元角分", str = "";
n += "00";
var indexpoint = n.indexOf('.'); // 如果是小数,截取小数点前面的位数
if (indexpoint >= 0) {
n = n.substring(0, indexpoint) + n.substr(indexpoint + 1, 2); // 若为小数,截取需要使用的unit单位
}
unit = unit.substr(unit.length - n.length); // 若为整数,截取需要使用的unit单位
for (var i = 0; i < n.length; i++) {
str += "零壹贰叁肆伍陆柒捌玖".charAt(n.charAt(i)) + unit.charAt(i); //遍历转化为大写的数字
}
return str.replace(/零(仟|佰|拾|角)/g, "零").replace(/(零)+/g, "零").replace(/零(万|亿|元)/g, "$1").replace(/(亿)万|壹(拾)/g, "$1$2").replace(/^元零?|零分/g, "").replace(/元$/g, "元整"); // 替换掉数字里面的零字符,得到结果
}
</script>
五、字符串相关
1、字符串替换(3.8及以上)
a = '啊啊'
b = '哦哦'
text = f'112{a}223{b}344'
==> 112啊啊223哦哦344
2、去除特殊字符(\xa0)
text = '08.317.01.60300402\xa0\xa0'
text = ''.join(text.split())
print([''.join(text.split())])