免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

怎么使用Python報表和日志

這篇文章主要介紹“怎么使用Python報表和日志”,在日常操作中,相信很多人在怎么使用Python報表和日志問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用Python報表和日志”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

目前累計服務客戶上1000家,積累了豐富的產(chǎn)品開發(fā)及服務經(jīng)驗。以網(wǎng)站設計水平和技術實力,樹立企業(yè)形象,為客戶提供成都做網(wǎng)站、成都網(wǎng)站建設、網(wǎng)站策劃、網(wǎng)頁設計、網(wǎng)絡營銷、VI設計、網(wǎng)站改版、漏洞修補等服務。成都創(chuàng)新互聯(lián)公司始終以務實、誠信為根本,不斷創(chuàng)新和提高建站品質,通過對領先技術的掌握、對創(chuàng)意設計的研究、對客戶形象的視覺傳遞、對應用系統(tǒng)的結合,為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進步。

導出Excel報表

報表就是用表格、圖表等格式來動態(tài)顯示數(shù)據(jù),所以有人用這樣的公式來描述報表:

報表 = 多樣的格式 + 動態(tài)的數(shù)據(jù)

有很多的三方庫支持在Python程序中寫Excel文件,包括xlwt、xlwings、openpyxl、xlswriter、pandas等,其中的xlwt雖然只支持寫xls格式的Excel文件,但在性能方面的表現(xiàn)還是不錯的。下面我們就以xlwt為例,來演示如何在Django項目中導出Excel報表,例如導出一個包含所有老師信息的Excel表格。

def export_teachers_excel(request):
 # 創(chuàng)建工作簿
 wb = xlwt.Workbook()
 # 添加工作表
 sheet = wb.add_sheet('老師信息表')
 # 查詢所有老師的信息(注意:這個地方稍后需要優(yōu)化)
 queryset = Teacher.objects.all()
 # 向Excel表單中寫入表頭
 colnames = ('姓名', '介紹', '好評數(shù)', '差評數(shù)', '學科')
 for index, name in enumerate(colnames):
 sheet.write(0, index, name)
 # 向單元格中寫入老師的數(shù)據(jù)
 props = ('name', 'detail', 'good_count', 'bad_count', 'subject')
 for row, teacher in enumerate(queryset):
 for col, prop in enumerate(props):
 value = getattr(teacher, prop, '')
 if isinstance(value, Subject):
 value = value.name
 sheet.write(row + 1, col, value)
 # 保存Excel
 buffer = BytesIO()
 wb.save(buffer)
 # 將二進制數(shù)據(jù)寫入響應的消息體中并設置MIME類型
 resp = HttpResponse(buffer.getvalue(), content_type='application/vnd.ms-excel')
 # 中文文件名需要處理成百分號編碼
 filename = quote('老師.xls')
 # 通過響應頭告知瀏覽器下載該文件以及對應的文件名
 resp['content-disposition'] = f'attachment; filename="{filename}"'
 return resp

映射URL。

urlpatterns = [
 # 此處省略上面的代碼
 path('excel/', views.export_teachers_excel),
 # 此處省略下面的代碼
]

生成前端統(tǒng)計圖表

如果項目中需要生成前端統(tǒng)計圖表,可以使用百度的ECharts。具體的做法是后端通過提供數(shù)據(jù)接口返回統(tǒng)計圖表所需的數(shù)據(jù),前端使用ECharts來渲染出柱狀圖、折線圖、餅圖、散點圖等圖表。例如我們要生成一個統(tǒng)計所有老師好評數(shù)和差評數(shù)的報表,可以按照下面的方式來做。

def get_teachers_data(request):
 # 查詢所有老師的信息(注意:這個地方稍后也需要優(yōu)化)
 queryset = Teacher.objects.all()
 # 用生成式將老師的名字放在一個列表中
 names = [teacher.name for teacher in queryset]
 # 用生成式將老師的好評數(shù)放在一個列表中
 good = [teacher.good_count for teacher in queryset]
 # 用生成式將老師的差評數(shù)放在一個列表中
 bad = [teacher.bad_count for teacher in queryset]
 # 返回JSON格式的數(shù)據(jù)
 return JsonResponse({'names': names, 'good': good, 'bad': bad})

映射URL。

urlpatterns = [
 # 此處省略上面的代碼
 path('teachers_data/', views.export_teachers_excel),
 # 此處省略下面的代碼
]

使用ECharts生成柱狀圖。

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>老師評價統(tǒng)計</title>
</head>
<body>
 <div id="main" style="width: 600px; height: 400px"></div>
 <p>
 <a href="/">返回首頁</a>
 </p>
 <script src="https://cdn.bootcss.com/echarts/4.2.1-rc1/echarts.min.js"></script>
 <script>
 var myChart = echarts.init(document.querySelector('#main'))
 fetch('/teachers_data/')
 .then(resp => resp.json())
 .then(json => {
 var option = {
 color: ['#f00', '#00f'],
 title: {
 text: '老師評價統(tǒng)計圖'
 },
 tooltip: {},
 legend: {
 data:['好評', '差評']
 },
 xAxis: {
 data: json.names
 },
 yAxis: {},
 series: [
 {
 name: '好評',
 type: 'bar',
 data: json.good
 },
 {
 name: '差評',
 type: 'bar',
 data: json.bad
 }
 ]
 }
 myChart.setOption(option)
 })
 </script>
</body>
</html>

運行效果如下圖所示。

怎么使用Python報表和日志

配置日志

項目開發(fā)階段,顯示足夠的調試信息以輔助開發(fā)人員調試代碼還是非常必要的;項目上線以后,將系統(tǒng)運行時出現(xiàn)的警告、錯誤等信息記錄下來以備相關人員了解系統(tǒng)運行狀況并維護代碼也是很有必要的。要做好這兩件事件,我們需要為Django項目配置日志。

Django的日志配置基本可以參照官方文檔再結合項目實際需求來進行,這些內容基本上可以從官方文檔上復制下來,然后進行局部的調整即可,下面給出一些參考配置。

LOGGING = {
 'version': 1,
 # 是否禁用已經(jīng)存在的日志器
 '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',
 },
 }
}

大家可能已經(jīng)注意到了,上面日志配置中的formatters是日志格式化器,它代表了如何格式化輸出日志,其中格式占位符分別表示:

  1. %(name)s - 記錄器的名稱

  2. %(levelno)s - 數(shù)字形式的日志記錄級別

  3. %(levelname)s - 日志記錄級別的文本名稱

  4. %(filename)s - 執(zhí)行日志記錄調用的源文件的文件名稱

  5. %(pathname)s - 執(zhí)行日志記錄調用的源文件的路徑名稱

  6. %(funcName)s - 執(zhí)行日志記錄調用的函數(shù)名稱

  7. %(module)s - 執(zhí)行日志記錄調用的模塊名稱

  8. %(lineno)s - 執(zhí)行日志記錄調用的行號

  9. %(created)s - 執(zhí)行日志記錄的時間

  10. %(asctime)s - 日期和時間

  11. %(msecs)s - 毫秒部分

  12. %(thread)d - 線程ID(整數(shù))

  13. %(threadName)s - 線程名稱

  14. %(process)d - 進程ID (整數(shù))

日志配置中的handlers用來指定日志處理器,簡單的說就是指定將日志輸出到控制臺還是文件又或者是網(wǎng)絡上的服務器,可用的處理器包括:

  1. logging.StreamHandler(stream=None) - 可以向類似與sys.stdout或者sys.stderr的任何文件對象輸出信息

  2. logging.FileHandler(filename, mode='a', encoding=None, delay=False) - 將日志消息寫入文件

  3. logging.handlers.DatagramHandler(host, port) - 使用UDP協(xié)議,將日志信息發(fā)送到指定主機和端口的網(wǎng)絡主機上

  4. logging.handlers.HTTPHandler(host, url) - 使用HTTP的GET或POST方法將日志消息上傳到一臺HTTP 服務器

  5. logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False) - 將日志消息寫入文件,如果文件的大小超出maxBytes指定的值,那么將重新生成一個文件來記錄日志

  6. logging.handlers.SocketHandler(host, port) - 使用TCP協(xié)議,將日志信息發(fā)送到指定主機和端口的網(wǎng)絡主機上

  7. logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=1.0) - 將日志輸出到指定的郵件地址

  8. logging.MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True) - 將日志輸出到內存指定的緩沖區(qū)中

上面每個日志處理器都指定了一個名為“l(fā)evel”的屬性,它代表了日志的級別,不同的日志級別反映出日志中記錄信息的嚴重性。Python中定義了六個級別的日志,按照從低到高的順序依次是:NOTSET、DEBUG、INFO、WARNING、ERROR、CRITICAL。

最后配置的日志記錄器是用來真正輸出日志的,Django框架提供了如下所示的內置記錄器:

  1. django - 在Django層次結構中的所有消息記錄器

  2. django.request - 與請求處理相關的日志消息。5xx響應被視為錯誤消息;4xx響應被視為為警告消息

  3. django.server - 與通過runserver調用的服務器所接收的請求相關的日志消息。5xx響應被視為錯誤消息;4xx響應被記錄為警告消息;其他一切都被記錄為INFO

  4. django.template - 與模板渲染相關的日志消息

  5. django.db.backends - 有與數(shù)據(jù)庫交互產(chǎn)生的日志消息,如果希望顯示ORM框架執(zhí)行的SQL語句,就可以使用該日志記錄器。

日志記錄器中配置的日志級別有可能不是最終的日志級別,因為還要參考日志處理器中配置的日志級別,取二者中級別較高者作為最終的日志級別。

配置Django-Debug-Toolbar

Django-Debug-Toolbar是項目開發(fā)階段輔助調試和優(yōu)化的神器,只要配置了它,就可以很方便的查看到如下表所示的項目運行信息,這些信息對調試項目和優(yōu)化Web應用性能都是至關重要的。

怎么使用Python報表和日志

1 . 安裝Django-Debug-Toolbar。

pip install django-debug-toolbar

2 . 配置 - 修改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,
}

3 . 配置 - 修改urls.py。

if settings.DEBUG:
 import debug_toolbar
 urlpatterns.insert(0, path('__debug__/', include(debug_toolbar.urls)))

4 . 使用 - 如下圖所示,在配置好Django-Debug-Toolbar之后,頁面右側會看到一個調試工具欄,上面包括了如前所述的各種調試信息,包括執(zhí)行時間、項目設置、請求頭、SQL、靜態(tài)資源、模板、緩存、信號等,查看起來非常的方便。

優(yōu)化ORM代碼

在配置了日志或Django-Debug-Toolbar之后,我們可以查看一下之前將老師數(shù)據(jù)導出成Excel報表的視圖函數(shù)執(zhí)行情況,這里我們關注的是ORM框架生成的SQL查詢到底是什么樣子的,相信這里的結果會讓你感到有一些意外。執(zhí)行Teacher.objects.all()之后我們可以注意到,在控制臺看到的或者通過Django-Debug-Toolbar輸出的SQL是下面這樣的:

SELECT `tb_teacher`.`no`, `tb_teacher`.`name`, `tb_teacher`.`detail`, `tb_teacher`.`photo`, `tb_teacher`.`good_count`, `tb_teacher`.`bad_count`, `tb_teacher`.`sno` FROM `tb_teacher`; args=()
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 101; args=(101,)
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 101; args=(101,)
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 101; args=(101,)
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 101; args=(101,)
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 103; args=(103,)
SELECT `tb_subject`.`no`, `tb_subject`.`name`, `tb_subject`.`intro`, `tb_subject`.`create_date`, `tb_subject`.`is_hot` FROM `tb_subject` WHERE `tb_subject`.`no` = 103; args=(103,)

這里的問題通常被稱為“1+N查詢”(或“N+1查詢”),原本獲取老師的數(shù)據(jù)只需要一條SQL,但是由于老師關聯(lián)了學科,當我們查詢到N條老師的數(shù)據(jù)時,Django的ORM框架又向數(shù)據(jù)庫發(fā)出了N條SQL去查詢老師所屬學科的信息。每條SQL執(zhí)行都會有較大的開銷而且會給數(shù)據(jù)庫服務器帶來壓力,如果能夠在一條SQL中完成老師和學科的查詢肯定是更好的做法,這一點也很容易做到,相信大家已經(jīng)想到怎么做了。是的,我們可以使用連接查詢,但是在使用Django的ORM框架時如何做到這一點呢?對于多對一關聯(lián)(如投票應用中的老師和學科),我們可以使用QuerySet的用select_related()方法來加載關聯(lián)對象;而對于多對多關聯(lián)(如電商網(wǎng)站中的訂單和商品),我們可以使用prefetch_related()方法來加載關聯(lián)對象。

在導出老師Excel報表的視圖函數(shù)中,我們可以按照下面的方式優(yōu)化代碼。

queryset = Teacher.objects.all().select_related('subject')

事實上,用ECharts生成前端報表的視圖函數(shù)中,查詢老師好評和差評數(shù)據(jù)的操作也能夠優(yōu)化,因為在這個例子中,我們只需要獲取老師的姓名、好評數(shù)和差評數(shù)這三項數(shù)據(jù),但是在默認的情況生成的SQL會查詢老師表的所有字段??梢杂肣uerySet的only()方法來指定需要查詢的屬性,也可以用QuerySet的defer()方法來指定暫時不需要查詢的屬性,這樣生成的SQL會通過投影操作來指定需要查詢的列,從而改善查詢性能,代碼如下所示:

queryset = Teacher.objects.all().only('name', 'good_count', 'bad_count')

當然,如果要統(tǒng)計出每個學科的老師好評和差評的平均數(shù),利用Django的ORM框架也能夠做到,代碼如下所示:

queryset = Teacher.objects.values('subject').annotate(
 good=Avg('good_count'), bad=Avg('bad_count'))

這里獲得的QuerySet中的元素是字典對象,每個字典中有三組鍵值對,分別是代表學科編號的subject、代表好評數(shù)的good和代表差評數(shù)的bad。如果想要獲得學科的名稱而不是編號,可以按照如下所示的方式調整代碼:

queryset = Teacher.objects.values('subject__name').annotate(
 good=Avg('good_count'), bad=Avg('bad_count'))

可見,Django的ORM框架允許我們用面向對象的方式完成關系數(shù)據(jù)庫中的分組和聚合查詢。

到此,關于“怎么使用Python報表和日志”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

當前標題:怎么使用Python報表和日志
本文URL:http://m.newbst.com/article12/gpijdc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供面包屑導航網(wǎng)站制作、網(wǎng)站建設、商城網(wǎng)站ChatGPT企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設