github链接 https://github.com/yt-xy/Django-blog
优化
抽象author基类
blog/base_admin.py
from django.contrib import admin
class BaseOwnerAdmin(admin.ModelAdmin):
"""
1.用来自动补充文章、分类、标签、侧边栏、友链这些Model的owner字段
2.用来针对queryset过滤当前用户的数据
"""
exclude = ('owner', )
def get_queryset(self, request):
qs = super(BaseOwnerAdmin, self).get_queryset(request)
return qs.filter(owner=request.user)
def save_model(self, request, obj, form, change):
obj.owner = request.user
return super(BaseOwnerAdmin, self).save_model(request, obj, form, change)
改造需要隔离不同用户数据的管理页面,只需要让对应的Admin继承这个类就可以了[其余App对应修改]
from blog.base_admin import BaseOwnerAdmin
...
@admin.register(Category, site=custom_site)
class CategoryAdmin(BaseOwnerAdmin):
...
# def save_model(self, request, obj, form, change):
# obj.owner = request.user
# return super(CategoryAdmin, self).save_model(request, obj, form, change)
记录操作日志
使用LogEntry
ModelAdmin内部提供内部提供了两个方法,分别是log_addition和log_change,一个是记录新增日志,一个是记录变更日志。
这两个方法均调用了LogEntry.objects.log_action方法,只是参数略有不同。如果需要自定义变更记录的话,只需要传递对应的参数即可。
user_id:当前用户id
content_type_id:要保存内容的类型,源代码(Django1.11)中使用的是get_content_type_for_model方法拿到对应Model的类型id,可以简单理解为ContentType为每个Model定义了一个类型id
object_id:记录变更实例的id,比如PostAdmin中它就是post.id
object_repr:实例的展示名称,可以简单理解为我们定义的__str__
返回的内容
action_flag:操作标记。admin的Model里面定义了几种基础的标记:ADDITION、CHANGE、DELETION,用来标记当前参数是数据变更、新增还是删除
change_message:记录的消息。可以自行定义,可以把新添加的内容放进去(必要时可以通过这里来恢复),也可以把新旧内容的区别放进去
查询某个对象的变更
假设记录的对象是Post的操作,现在来获取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).pk,
object_id = post.id
)
在admin页面上查看操作日志
blogs/admin.py
from django.contrib.admin.models import LogEntry
...
@admin.register(LogEntry, site=custom_site)
class LogEntryAdmin(admin.ModelAdmin):
list_display = ['object_repr', 'object_id', 'action_flag', 'user', 'change_message']