如何通过OneToOneField获取用户最后登录时间并在Django Admin面板展示?
解决Django Admin中Profile列表展示用户最后登录时间的问题
问题原因
Django Admin的list_display不支持直接使用user__last_login这种跨关联模型的双下划线字段写法,系统会判定这不是Profile模型的属性、ProfileAdmin的方法或可调用对象,从而抛出admin.E108错误。
解决方案
方法1:自定义方法展示关联字段
在ProfileAdmin类中添加自定义方法,通过关联的user对象获取last_login值:
@admin.register(models.Profile) class ProfileAdmin(admin.ModelAdmin): list_display = [ 'user', 'first_name', 'last_name', 'get_user_last_login', ] def get_user_last_login(self, obj): return obj.user.last_login if obj.user else None # 设置列表中的列名 get_user_last_login.short_description = '最后登录时间'
方法2:支持排序的优化写法
如果需要让这一列支持排序,可以结合display()装饰器实现:
from django.contrib import admin @admin.register(models.Profile) class ProfileAdmin(admin.ModelAdmin): list_display = [ 'user', 'first_name', 'last_name', 'get_user_last_login', ] @admin.display(description='最后登录时间', ordering='user__last_login') def get_user_last_login(self, obj): if obj.user and obj.user.last_login: return obj.user.last_login.strftime('%Y-%m-%d %H:%M:%S') return '从未登录'
代码说明
- 自定义方法接收
obj参数(当前Profile实例),通过obj.user访问关联的User对象,进而获取last_login。 - 处理
obj.user为None的情况(模型中user字段设置了null=True),避免抛出AttributeError。 - 使用
@admin.display装饰器可以直接设置列名和排序依据,ordering='user__last_login'指定根据关联User模型的last_login字段进行排序。
内容的提问来源于stack exchange,提问作者Rustem
相关产品推荐
相关产品推荐

