You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Admin自定义字段报can't adapt type 'Actor'错误解决

错误说明

ProgrammingError: can't adapt type 'Actor'是数据库驱动抛出的类型适配异常:传入SQL查询的参数包含Django的Actor模型实例,驱动无法将该Python对象转换为数据库可识别的合法值类型,导致SQL执行失败。

触发原因

错误出在自定义方法movies_count的原生SQL逻辑:

  • SQL语句中占位符对应的是actor_name字段的字符串值,但传入的参数为[obj],此处obj是当前行对应的Actor模型实例,并非演员名字符串,驱动无法解析该类型参数。
  • 现有逻辑存在冗余:查询多对多中间表的关联记录时,完全不需要嵌套子查询查演员ID,直接用当前实例的主键匹配actor_id即可。
  • 现有写法存在明显性能问题:Admin列表每渲染一行演员记录,就会发起一次独立的数据库查询,属于典型的N+1查询问题,数据量上升后页面加载速度会严重下降。
  • 额外隐患:原生SQL参数拼接写法存在SQL注入风险。
快速修复方案

如果要保留原生SQL写法,修正参数传递和查询逻辑即可:

def movies_count(self, obj):
    # 直接用当前演员主键匹配中间表actor_id,参数传整数类型的obj.id,驱动可正常适配
    count = Actor.objects.raw(
        'select count(*) as total from movies_movie_actors where actor_id=%s',
        [obj.id]
    )[0].total
    return count
movies_count.short_description = '参演电影数量'
推荐实现方案

用Django ORM的聚合+反向关联实现,同时解决N+1查询问题,性能更好也更安全:

  1. 先修正Movie模型中多对多字段的大小写错误,否则反向关联会失效:
    # 原写法是'actors.actor',模型类名为Actor,首字母需大写
    actors = models.ManyToManyField('actors.Actor')
    

    可选优化:给多对多字段添加related_name='movies'参数,方便后续反向查询

  2. 重写ActorAdmin的查询集方法,提前聚合所有演员的参演电影数,避免逐行查库:
    from django.contrib import admin
    from django.db.models import Count
    from actors.models import Actor
    
    
    @admin.register(Actor)
    class ActorAdmin(admin.ModelAdmin):
        search_fields = ('actor_name',)
        list_filter = ('gender',)
        list_display = ['actor_name', 'age', 'gender', 'movies_count']
        readonly_fields = ['movies_count']
    
        def get_queryset(self, request):
            qs = super().get_queryset(request)
            # 一次性聚合所有演员的关联电影数,如果加了related_name='movies'就把'movie'改成'movies'
            return qs.annotate(_movies_count=Count('movie'))
    
        def movies_count(self, obj):
            return obj._movies_count
        movies_count.short_description = '参演电影数量'
    

内容的提问来源于stack exchange,提问作者Abdelrahman Saleh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 13:54:22