Django Admin如何展示ManyToManyFields 解决likes多对多字段显示报错
问题原因
你遇到的'User' object has no attribute 'likes'报错根源是逻辑混淆:
你在Item模型中定义的likes是指向User模型的多对多字段,obj.likes.all()返回的是给当前Item点赞的所有User实例,你遍历的每个p都是User对象,User模型本身没有定义likes字段,自然无法访问p.likes。
你定义的related_name='blog_posts'是反向查询参数,作用是让User实例可以通过user.blog_posts.all()查询该用户点赞过的所有Item条目,不是给User新增likes属性。
修复方案
直接修改Admin类中的自定义展示方法,从User实例取你需要展示的属性(比如用户名、邮箱等)即可,示例如下:
from django.contrib import admin from .models import Item class ItemAdmin(admin.ModelAdmin): # 把原来的get_products替换为更贴合语义的方法名 list_display = ('title','author','item_category','date','get_likes_users') list_filter = ('item_category',) def get_likes_users(self, obj): # 取所有点赞用户的用户名,用逗号分隔展示 return ", ".join([user.username for user in obj.likes.all()]) # 配置Admin列表页该列的显示名称 get_likes_users.short_description = "点赞用户"
如果你需要每行展示一个点赞用户,可以用HTML换行标签配合安全渲染实现:
from django.contrib import admin from django.utils.safestring import mark_safe from .models import Item class ItemAdmin(admin.ModelAdmin): list_display = ('title','author','item_category','date','get_likes_users') list_filter = ('item_category',) def get_likes_users(self, obj): user_name_list = [user.username for user in obj.likes.all()] return mark_safe("<br>".join(user_name_list)) get_likes_users.short_description = "点赞用户" # 兼容旧版本Django的HTML渲染许可配置 get_likes_users.allow_tags = True
内容的提问来源于stack exchange,提问作者Waqart
相关产品推荐
相关产品推荐

