配置日志
LOGGING = {
'version': 1,
# 是否禁用已经存在的日志器
'disable_existing_loggers': False,
# 日志格式化器
'formatters': {
'simple': {
'format': '%(asctime)s %(module)s.%(funcName)s: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
},
'verbose': {
'format': '%(asctime)s %(levelname)s [%(process)d-%(threadName)s] '
'%(module)s.%(funcName)s line %(lineno)d: %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S',
}
},
# 日志过滤器
'filters': {
# 只有在Django配置文件中DEBUG值为True时才起作用
'require_debug_true': {
'()': 'django.utils.log.RequireDebugTrue',
},
},
# 日志处理器
'handlers': {
# 输出到控制台
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'filters': ['require_debug_true'],
'formatter': 'simple',
},
# 输出到文件(每周切割一次)
'file1': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': 'access.log',
'when': 'W0',
'backupCount': 12,
'formatter': 'simple',
'level': 'INFO',
},
# 输出到文件(每天切割一次)
'file2': {
'class': 'logging.handlers.TimedRotatingFileHandler',
'filename': 'error.log',
'when': 'D',
'backupCount': 31,
'formatter': 'verbose',
'level': 'WARNING',
},
},
# 日志器记录器
'loggers': {
'django': {
# 需要使用的日志处理器
'handlers': ['console', 'file1', 'file2'],
# 是否向上传播日志信息
'propagate': True,
# 日志级别(不一定是最终的日志级别)
'level': 'DEBUG',
},
}
}
配置Django-Debug-Toolbar
-
安装Django-Debug-Toolbar。
pip install django-debug-toolbar
-
配置 - 修改settings.py。
INSTALLED_APPS = [ 'debug_toolbar', ] MIDDLEWARE = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', ] DEBUG_TOOLBAR_CONFIG = { # 引入jQuery库 'JQUERY_URL': 'https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js', # 工具栏是否折叠 'SHOW_COLLAPSED': True, # 是否显示工具栏 'SHOW_TOOLBAR_CALLBACK': lambda x: True, }
-
配置 - 修改urls.py。
if settings.DEBUG: import debug_toolbar urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls)))
使用 - 如下图所示,在配置好Django-Debug-Toolbar之后,页面右侧会看到一个调试工具栏,上面包括了如前所述的各种调试信息,包括执行时间、项目设置、请求头、SQL、静态资源、模板、缓存、信号等,查看起来非常的方便。
django查询
用select_related()和prefetch_related()执行预加载避免“1+N查询问题”。
.select_related外连接查询
only() / defer()只查询括号内属性
defer()、only()等缓解内存压力。
Emp.objects.filter(pk=7800).only('name', 'sal')
(0.001) SELECTTbEmp
.empno
,TbEmp
.ename
,TbEmp
.sal
FROMTbEmp
WHERETbEmp
.empno
= 7800 LIMIT 21; args=(7800,)
<QuerySet [<Emp: Emp object (7800)>]>
Emp.objects.filter(pk=7800).defer('name', 'sal')
(0.001) SELECTTbEmp
.empno
,TbEmp
.job
,TbEmp
.mgr
,TbEmp
.comm
,TbEmp
.dno
FROMTbEmp
WHERETbEmp
.empno
= 7800 LIMIT 21; args=(7800,)
<QuerySet [<Emp: Emp object (7800)>]>
.only('name','good_count','bad_count')
.values('subject__name').annotate(good=Avg('good_count'),bad=Avg('bad_count'))
3.echarts 前端渲染使用报表
echarts 前端渲染使用报表
ECharts或Chart.js。
思路:后端只提供JSON格式的数据,前端JavaScript渲染生成图表。
def get_charts_data(request):
"""获取统计图表JSON数据"""
names = []
totals = []
# 通过connections获取指定数据库连接并创建游标对象
with connections['backend'].cursor() as cursor:
# 在使用ORM框架时可以使用对象管理器的aggregate()和annotate()方法实现分组和聚合函数查询
# 执行原生SQL查询(如果ORM框架不能满足业务或性能需求)
cursor.execute('select dname, total from vw_dept_emp')
for row in cursor.fetchall():
names.append(row[0])
totals.append(row[1])
return JsonResponse({'names': names, 'totals': totals})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>统计图表</title>
<style>
#main {
width: 600px;
height: 400px;
}
</style>
</head>
<body>
<div id="main"></div>
<script src="https://cdn.bootcss.com/echarts/4.2.0-rc.2/echarts.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
var myChart = echarts.init($('#main')[0]);
$.ajax({
'url': 'charts_data',
'type': 'get',
'data': {},
'dataType': 'json',
'success': function(json) {
var option = {
title: {
text: '员工分布统计图'
},
tooltip: {},
legend: {
data:['人数']
},
xAxis: {
data: json.names
},
yAxis: {},
series: [{
name: '人数',
type: 'bar',
data: json.totals
}]
};
myChart.setOption(option);
},
'error': function() {}
});
</script>
</body>
</html>
4.q对象组合查询
queryset = Record1.objects.filter(
Q(carno__iexact=carno) | Q(owner__contains=carno)
)
说明:Q对象主要用来解决多条件组合的复杂查询;F对象主要用于更新数据。
from django.db.models import Q
Emp.objects.filter(
... Q(name__startswith='张'),
... Q(sal__lte=5000) | Q(comm__gte=1000)
... ) # 查询名字以“张”开头且工资小于等于5000或补贴大于等于1000的员工
<QuerySet [<Emp: 张三丰>]>
<td>{{ record.dealt|yesno:'已受理,未受理' }}</td>
5.基于like的模糊查询
contains / icontains / startswith / istartswith / endswith / iendswith:基于like的模糊查询
首先你要先导入Paginator
from django.core.paginator import Paginator
django分页器
创建分页对象 然后通过这个对象来调用分页的所有的属性
paginator = Paginator(book_list, 2) #设置每一页显示几条 创建一个panginator对象
book_list = paginator.page(1) #这个是对你的分页的数据进行取值 去除你的分过后的第一页