Django中如何通过表单为多对多关系添加关联对象
Django 给已有Workout实例关联新增Exercise的实现方案
错误原因
- 你的代码逻辑是同时新建Workout与Exercise实例,不符合「给已有Workout添加Exercise」的需求,无需实例化Workout相关表单
- Django 多对多字段不支持直接用
=赋值,关联的两个实例必须先在数据库保存生成主键后,调用add()/set()等方法完成关联
实现步骤
1. 配置URL路由
在urls.py中添加路由,用于接收URL中传递的Workout ID:
from django.urls import path from . import views urlpatterns = [ # 其他现有路由 path('workout/<int:workout_id>/add-exercise/', views.add_exercise_to_workout, name='add_exercise'), ]
2. 编写视图逻辑
from django.shortcuts import get_object_or_404, redirect, render from .models import Workout from .forms import NovoExercise def add_exercise_to_workout(request, workout_id): # 从URL参数获取对应Workout实例,不存在则返回404 target_workout = get_object_or_404(Workout, id=workout_id) if request.method == 'POST': exercise_form = NovoExercise(request.POST) if exercise_form.is_valid(): # 先保存Exercise实例到数据库 new_exercise = exercise_form.save() # 将新Exercise关联到目标Workout target_workout.exercises.add(new_exercise) # 操作完成后跳转回Workout详情页(可根据自己的实际路由修改跳转规则) return redirect('workout_detail', workout_id=target_workout.id) else: exercise_form = NovoExercise() return render(request, 'add_exercise.html', { 'form': exercise_form, 'workout': target_workout })
3. 模板表单配置
页面中+按钮对应的表单,action属性填写对应带Workout ID的路由即可:
<form method="POST" action="{% url 'add_exercise' workout.id %}"> {% csrf_token %} {{ form.as_p }} <button type="submit">+ 添加训练动作</button> </form>
补充说明
如果你的Exercise实例仅属于一个Workout,不需要多实例复用,可以调整模型设计,把Workout中的多对多字段删掉,改为在Exercise模型中添加外键关联Workout,关联逻辑会更简单。
内容的提问来源于stack exchange,提问作者overclock
相关产品推荐
相关产品推荐

