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

Django调用Workout.objects.all()出现TypeError的原因排查

解决Django自定义字段from_db_value()参数不匹配的错误

你遇到的这个报错根源很明确——自定义字段的from_db_value()方法参数签名和当前Django版本不兼容。

问题分析

Django在版本迭代中给from_db_value()方法新增了第5个参数context,而你定义的LiftsField和CardiosField里的这个方法只声明了4个参数(value, expression, connection),当Django尝试传入完整的5个参数时,就触发了参数不匹配的类型错误。

另外还要提个隐藏问题:你的parse_cardios函数没有返回值,这会导致CardiosField在解析数据库值时返回None,后续必然会引发新的逻辑错误,这个也要一起修复。

修复步骤

  1. 给两个自定义字段的from_db_value()方法添加context参数(可以设置默认值None,避免影响现有逻辑)
  2. 补全parse_cardios函数的返回语句

修改后的fields.py代码如下:

import json
# 请确保导入了对应的models模块,比如from . import models

def parse_lifts(lifts_string):
    """Takes a string of json and turns it into a Lifts object"""
    series = json.loads(lifts_string)
    serie_objects = [models.LiftSerie(serie["liftname"], serie["setlist"]) for serie in series]
    return models.Lifts(serie_objects)

def parse_cardios(cardios_string):
    """Takes a string of json and turns it into a Cardios Object"""
    series = json.loads(cardios_string)
    serie_objects = [models.CardioSerie(serie["cardioname"], serie["duration"]) for serie in series]
    # 补全返回语句,返回构建好的Cardios对象
    return models.Cardios(serie_objects)

class LiftsField(JSONField):
    """Field representing a models.Lifts object"""
    # 添加context参数并设置默认值None
    def from_db_value(self, value, expression, connection, context=None):
        if value is None:
            return value
        return parse_lifts(value)
    def to_python(self, value):
        if isinstance(value, models.Lifts):
            return value
        if value is None:
            return value
        return parse_lifts(value)
    def get_prep_value(self, value):
        if not value:
            return value
        lifts_pre_json = [serie_object.pre_json() for serie_object in value.series]
        return json.dumps(lifts_pre_json)

class CardiosField(JSONField):
    """Field representing a models.Cardios object"""
    # 添加context参数并设置默认值None
    def from_db_value(self, value, expression, connection, context=None):
        if value is None:
            return value
        return parse_cardios(value)
    def to_python(self, value):
        if isinstance(value, models.Cardios):
            return value
        if value is None:
            return value
        return parse_cardios(value)
    def get_prep_value(self, value):
        if value == None:
            return value
        cardios_pre_json = [serie_object.pre_json() for serie_object in value.series]
        return json.dumps(cardios_pre_json)

验证修复

修改代码后重启Django Shell,再次执行Workout.objects.all(),应该就能正常返回查询集了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:26:13