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

Django中DeferredAttribute与int相加的TypeError问题排查与解决

错误成因
  • 混淆了模型类和模型实例的用法:代码中watchlist是你的模型类名,watchlist.number_ratings调用的是模型的字段定义(DeferredAttribute类型),而非从数据库取出的具体实例的数值,因此无法和整数1执行加法操作。你实际应该操作的是通过watchlist.objects.get(pk=pk)获取的实例watchlist_movie。
解决方法

修改代码中所有错误引用watchlist.xxx的地方,替换为实例watchlist_movie.xxx,修正后的perform_create方法代码如下:

def perform_create(self, serializer):    
    pk = self.kwargs.get('pk')           
    watchlist_movie = watchlist.objects.get(pk=pk)

    review_user = self.request.user        
    review_queryset = Review.objects.filter(watchlist=watchlist_movie, review_user=review_user)

    if review_queryset.exists():        
        raise ValidationError('You have already reviewed this movie.')
    
    if watchlist_movie.number_ratings == 0:
        watchlist_movie.avg_rating = serializer.validated_data['rating']
    else:
        watchlist_movie.avg_rating = (watchlist_movie.avg_rating + serializer.validated_data['rating']) / 2

    watchlist_movie.number_ratings = watchlist_movie.number_ratings + 1
    watchlist_movie.save()

    serializer.save(watchlist = watchlist_movie, review_user = review_user)

另外,推荐使用Django的F()表达式实现原子更新,避免并发场景下的统计错误,将数值更新代码替换为:

from django.db.models import F

watchlist_movie.number_ratings = F('number_ratings') + 1

该方式会直接在数据库层面执行更新操作,不会出现多用户同时操作时的数值覆盖问题。

未来避免这类错误的建议
  • 严格区分模型类和模型实例:模型类是数据表的抽象定义,实例才对应数据库中的具体数据行,操作字段值必须使用实例。
  • 调试时打印变量类型:遇到类型错误时,用print(type(变量名))确认变量类型,快速定位是类属性还是实例属性。
  • 数值更新场景优先用F()表达式:既避免类型错误,也能保证并发操作的原子性。

内容的提问来源于stack exchange,提问作者Rohit Gajula

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:32:57