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

Django项目中'QuerySet'无'Breakdown'属性错误的解决方法

解决指定Workout下Exercise的Breakdown数据展示问题

先明确模型关联逻辑(参考示例)

假设你的模型结构如下(如果实际结构不同,对应调整关联字段和反向名称):

class Workout(models.Model):
    name = models.CharField(max_length=100)
    # 其他训练相关字段

class Exercise(models.Model):
    workout = models.ForeignKey(Workout, on_delete=models.CASCADE, related_name='exercises')
    name = models.CharField(max_length=100)
    # 其他动作相关字段

class Breakdown(models.Model):
    exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, related_name='breakdowns')
    repetitions = models.IntegerField()
    order = models.IntegerField()
    # 其他组次相关字段

错误原因分析

你执行breakdowns=excercises.Breakdown.repetitions.all()报错,是因为excercises(注意还有拼写错误,正确是exercises)是QuerySet对象(多个Exercise实例的集合),而非单个Exercise对象,无法直接通过它访问Breakdown关联模型。

正确实现方案

方案1:预加载关联数据(高效推荐)

用prefetch_related一次性拉取所有关联数据,避免多次数据库查询,同时指定Breakdown按order排序:

from django.db.models import Prefetch

def workout_details(request, workout_id):
    # 获取指定Workout,同时预加载关联的Exercise和对应的Breakdown
    workout = Workout.objects.prefetch_related(
        Prefetch(
            'exercises__breakdowns',
            queryset=Breakdown.objects.order_by('order'),
            to_attr='sorted_breakdowns'
        )
    ).get(id=workout_id)
    
    return render(request, 'workout_details.html', {'workout': workout})

模板中遍历展示:

<h1>{{ workout.name }} 训练详情</h1>
{% for exercise in workout.exercises %}
    <h3>{{ exercise.name }}</h3>
    <ul>
        {% for breakdown in exercise.sorted_breakdowns %}
            <li>第{{ breakdown.order }}组: {{ breakdown.repetitions }}次</li>
        {% endfor %}
    </ul>
{% endfor %}

方案2:逐个遍历Exercise获取Breakdown

如果不需要预加载,可直接遍历每个Exercise实例获取对应的Breakdown:

def workout_details(request, workout_id):
    workout = Workout.objects.get(id=workout_id)
    # 整理每个动作及其对应的组次数据
    exercise_data = []
    for exercise in workout.exercises.all():
        # 获取当前动作的所有组次,按order排序
        breakdowns = exercise.breakdowns.all().order_by('order')
        exercise_data.append({
            'exercise': exercise,
            'breakdowns': breakdowns
        })
    
    return render(request, 'workout_details.html', {'exercise_data': exercise_data})

模板中遍历展示:

<h1>训练详情</h1>
{% for item in exercise_data %}
    <h3>{{ item.exercise.name }}</h3>
    <ul>
        {% for breakdown in item.breakdowns %}
            <li>顺序{{ breakdown.order }}: {{ breakdown.repetitions }}次</li>
        {% endfor %}
    </ul>
{% endfor %}

注意事项

  • 拼写检查:确保代码中是exercises而非excercises,避免不必要的错误。
  • 反向关联名称:如果Exercise模型的ForeignKey未设置related_name,默认反向关联名为exercise_set,需将代码中的workout.exercises.all()改为workout.exercise_set.all()。
  • 数据校验:确认数据库中存在指定Workout关联的Exercise和Breakdown记录,避免无结果的情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:06:52