Django利用LogEntry生成歷史操作實(shí)戰(zhàn)記錄
在開(kāi)發(fā)測(cè)試平臺(tái)的時(shí)候,雖然對(duì)某些關(guān)鍵功能做了權(quán)限設(shè)置,但畢竟是公司多人使用,有些數(shù)據(jù)的配置可能不小心被他人修改但未告知其他使用者,造成了諸多不便。所以決定開(kāi)發(fā)一個(gè)操作歷史表,可以方便查看數(shù)據(jù)地改動(dòng)。
LogEntry是在后臺(tái)開(kāi)發(fā)中經(jīng)常用到的模塊,它在admin是默認(rèn)開(kāi)啟的。
可以使用LogEntry模塊記錄所有用戶(hù)的操作記錄。一方面可以用來(lái)監(jiān)督,另一方面可以用來(lái)做回滾。
使用LogEntry
ModelAdmin本身就有日志記錄功能。當(dāng)新建一個(gè)實(shí)體(Post、Category、Tag)時(shí),ModelAdmin會(huì)創(chuàng)建一條變更日志記錄。當(dāng)修改一條內(nèi)容時(shí),ModelAdmin又會(huì)調(diào)用LogEntry來(lái)創(chuàng)建一條日志,記錄這個(gè)變更。
ModelAdmin內(nèi)部提供了兩個(gè)方法,分別是log_addition和log_change。
log_addition記錄新增日志。
log_change記錄變更日志。
log_deletion記錄刪除日志。
我們可以看它們的定義來(lái)學(xué)習(xí)LogEntry模塊
代碼位置:Lib\site-packages\django\contrib\admin\options.py
def log_addition(self, request, object, message): """ Log that an object has been successfully added. The default implementation creates an admin LogEntry object. """ from django.contrib.admin.models import LogEntry, ADDITION return LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=get_content_type_for_model(object).pk, object_id=object.pk, object_repr=str(object), action_flag=ADDITION, change_message=message, ) def log_change(self, request, object, message): """ Log that an object has been successfully changed. The default implementation creates an admin LogEntry object. """ from django.contrib.admin.models import LogEntry, CHANGE return LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=get_content_type_for_model(object).pk, object_id=object.pk, object_repr=str(object), action_flag=CHANGE, change_message=message, ) def log_deletion(self, request, object, object_repr): """ Log that an object will be deleted. Note that this method must be called before the deletion. The default implementation creates an admin LogEntry object. """ from django.contrib.admin.models import LogEntry, DELETION return LogEntry.objects.log_action( user_id=request.user.pk, content_type_id=get_content_type_for_model(object).pk, object_id=object.pk, object_repr=object_repr, action_flag=DELETION, )
從以上代碼可以看出:這兩個(gè)方法都調(diào)用了LogEntry.objects.log_action方法,只是參數(shù)略有不同,可以看到,如果需要自定義變更記錄的話,只需要傳遞對(duì)應(yīng)的參數(shù)即可。以下簡(jiǎn)要介紹一下這些參數(shù)。
- user_id:當(dāng)前用戶(hù)id
- content_type_id:要保存內(nèi)容的類(lèi)型,上面的代碼中使用的是get_.content_type_for_model方法拿到對(duì)應(yīng)Model的類(lèi)型id。這可以簡(jiǎn)單理解為ContentType為每個(gè)Model定義了一個(gè)類(lèi)型id
- object_id:記錄變更實(shí)例的id
- object_repr:實(shí)例的展示名稱(chēng),可以簡(jiǎn)單理解為我們定義的__str__所返回的內(nèi)容
- action_flag:操作標(biāo)記。admin的Model里面定義了幾種基礎(chǔ)的標(biāo)記: ADDITION、CHANGE和DELETION。它用來(lái)標(biāo)記當(dāng)前參數(shù)是數(shù)據(jù)變更、新增,還是刪除。
- change_message:這是記錄的消息,可以自行定義。我們可以把新添加的內(nèi)容放進(jìn)去(必要時(shí)可以通過(guò)這里來(lái)恢復(fù)),也可以把新舊內(nèi)容的區(qū)別放進(jìn)去。
理解了這幾個(gè)參數(shù),如果遇到類(lèi)似的需求,就能直接使用Django現(xiàn)成的工具來(lái)完成了。
查詢(xún)某個(gè)對(duì)象的變更
上面我們知道如何記錄某個(gè)對(duì)象的變更日志了,那么問(wèn)題來(lái)了,如何在詢(xún)已經(jīng)記錄的變更呢?
其實(shí)這是簡(jiǎn)單的Model查詢(xún)問(wèn)題。假設(shè)我們記錄的對(duì)象是Post的操作,現(xiàn)在來(lái)獲取Post中id為1的所有變更日志,大概代碼如下:
from django.contrib.admin.models import LogEntry, CHANGE from django.contrib.admin.options import get_content_type_for_model post = Post.objects.get(id=1) log_entries = LogEntry.objects.filter( content_type_id=get_content_type_for_model(post).id, object_id=post.id)
這樣我們就拿到了id為1的所有變更記錄了。
在admin頁(yè)面上查看操作日志
我們既知道如何記錄變更日志,也知道如何獲取變更日志,那么如何才能夠在admin后臺(tái)方便地查看操作日志呢?
新增如下配置(admin.py):
#最上面增加import from django.contrib.admin.models import LogEntry #文件最下方增加 @adnin.register(LogEntry, site=custom_site) class LogEntryAdmin(admin.ModelAdmin): list_display = ['object_repr','object_ id','action_flag','user','change_message']
這樣就可以看到所有的變更記錄了。如下圖所示:
實(shí)戰(zhàn)
雖然操作歷史顯示出來(lái)了,但是在django自帶的admin后臺(tái)才能看到,不是所有人都有進(jìn)入admin后臺(tái)權(quán)限,能不能有一種方法能在前端展示出來(lái)讓每個(gè)人都可以查看呢?
前端代碼:
<table class="table table-bordered" style="width: 60%;margin-left: 20%;text-align: center"> <caption style="text-align: center"> <span style="font-size: large;color: black">項(xiàng)目:【<span style="color: pink">{{ client.name }}</span>】的操作記錄: </span> </caption> <thead> <tr style="background-color: #cdd8e5"> <th style="width: 100px;text-align: center">操作時(shí)間</th> <th style="width: 200px;text-align: center">操作對(duì)象</th> <th style="width: 50px;text-align: center">對(duì)象id</th> <th style="width: 100px;text-align: center">動(dòng)作標(biāo)志</th> <th style="width: 100px;text-align: center">操作用戶(hù)</th> <th style="width: 300px;text-align: center">修改內(nèi)容</th> </tr> </thead> <tbody> {% for i in objects %} <tr> <td>{{ i.action_time }}</td> <td>{{ i.object_repr }}</td> <td>{{ i.object_id }}</td> <td>{{ i.get_action_flag_display }}</td> <td>{{ i.user }}</td> <td>{{ i.change_message }}</td> </tr> {% endfor %} </tbody> </table>
這里有個(gè)坑,如果就利用{{i.action_flag}}獲取操作標(biāo)記的話,得到的是索引值,經(jīng)過(guò)stackoverflow.com查閱,需要利用Django-doc(用您要在其文本表示形式中“翻譯”的字段名稱(chēng)替換)來(lái)獲取相應(yīng)值,因此:get_fieldname_display,所以這里要寫(xiě)成{{ i.get_action_flag_display }}
后端代碼(views.py):
# 導(dǎo)入所需的包 from django.contrib.admin.models import LogEntry, CHANGE, ADDITION, DELETION from django.contrib.admin.options import get_content_type_for_model res = dict() res['objects'] = LogEntry.objects.all() # 獲取到所有操作歷史 # 只需要調(diào)用LogEntry.objects.log_action方法帶入所需參數(shù)即可 LogEntry.objects.log_action( user_id=request.user.pk, # 操作用戶(hù)的id content_type_id=get_content_type_for_model(object).pk, # 對(duì)應(yīng)數(shù)據(jù)庫(kù)Model的id object_id=object.pk, # 操作對(duì)象的id object_repr=object_repr, # 操作對(duì)象的名字 action_flag=DELETION, # ADDITION、CHANGE和DELETION三種方式選擇合適的 change_message='' # 自定義消息,可以放入修改之后的數(shù)據(jù) )
實(shí)現(xiàn)效果
參考資料:https://www.cnblogs.com/zihao1037/p/11057341.html
到此這篇關(guān)于Django利用LogEntry生成歷史操作的文章就介紹到這了,更多相關(guān)Django歷史操作內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python Django框架單元測(cè)試之文件上傳測(cè)試示例
這篇文章主要介紹了Python Django框架單元測(cè)試之文件上傳測(cè)試,結(jié)合實(shí)例形式分析了Django框架單元測(cè)試中文件上傳測(cè)試的操作步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-05-05Flask 讓jsonify返回的json串支持中文顯示的方法
下面小編就為大家分享一篇Flask 讓jsonify返回的json串支持中文顯示的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03Python使用fliecmp實(shí)現(xiàn)比較文件的操作
對(duì)于文件的比較一般有幾種,比如比較文件的內(nèi)容,比較文件的大小,或者直接對(duì)比整個(gè)項(xiàng)目文件,本文就詳細(xì)的介紹這些方法的實(shí)現(xiàn),感興趣的可以了解一下2021-06-06關(guān)于python中readlines函數(shù)的參數(shù)hint的相關(guān)知識(shí)總結(jié)
今天給大家?guī)?lái)的是關(guān)于Python函數(shù)的相關(guān)知識(shí),文章圍繞著python中readlines函數(shù)的參數(shù)hint展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06Pygame游戲開(kāi)發(fā)之太空射擊實(shí)戰(zhàn)盾牌篇
相信大多數(shù)8090后都玩過(guò)太空射擊游戲,在過(guò)去游戲不多的年代太空射擊自然屬于經(jīng)典好玩的一款了,今天我們來(lái)自己動(dòng)手實(shí)現(xiàn)它,在編寫(xiě)學(xué)習(xí)中回顧過(guò)往展望未來(lái),在本課中,我們將為玩家添加一個(gè)盾牌以及一個(gè)用于顯示盾牌等級(jí)的欄2022-08-08Django自定義YamlField實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了Django自定義YamlField實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11python3使用matplotlib繪制散點(diǎn)圖
這篇文章主要為大家詳細(xì)介紹了python3使用matplotlib繪制散點(diǎn)圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03pytorch 數(shù)據(jù)預(yù)加載的實(shí)現(xiàn)示例
在PyTorch中,數(shù)據(jù)加載和預(yù)處理是深度學(xué)習(xí)中非常重要的一部分,本文主要介紹了pytorch 數(shù)據(jù)預(yù)加載的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12