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

Django:如何自动为用户模型填充多对多字段关联

解决方案

要实现点击提交按钮就把当前SingleWorkout实例添加到登录用户的completed_workouts多对多字段中,且不显示任何选择框,你需要调整表单和视图的逻辑,具体如下:

1. 简化表单(forms.py)

不需要使用UserChangeForm,因为你不需要用户输入任何字段,直接创建一个空表单即可:

from django import forms

class CompleteWorkoutForm(forms.Form):
    # 空表单,仅用于触发提交逻辑
    pass

2. 调整视图逻辑(views.py)

使用FormView(而非UpdateView,因为你不需要更新SingleWorkout实例,只是给用户添加关联),在form_valid方法中完成多对多关系的添加:

from django.views.generic.edit import FormView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy
from .models import SingleWorkout

class WorkoutCompleteView(LoginRequiredMixin, FormView):
    template_name = 'workout/daily_view.html'
    form_class = CompleteWorkoutForm
    success_url = reverse_lazy("template")

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # 获取当前页面对应的SingleWorkout实例
        context['workout'] = SingleWorkout.objects.get(slug=self.kwargs['slug'])
        return context

    def form_valid(self, form):
        # 获取当前登录用户
        current_user = self.request.user
        # 获取要添加的SingleWorkout实例
        target_workout = SingleWorkout.objects.get(slug=self.kwargs['slug'])
        # 添加到多对多字段
        current_user.completed_workouts.add(target_workout)
        # 执行父类逻辑完成重定向
        return super().form_valid(form)

3. 修改模板

移除表单字段的渲染,只保留提交按钮:

{{ workout }}
<br>
workout:
<br>
{{ workout.exercise_1 }}
<br>
{{ workout.description_1 }}
<form method="POST">
    {% csrf_token %}
    <!-- 无需显示任何表单字段 -->
    <input type="submit" value="Confirm">
</form>

关键说明

  • 逻辑位置:多对多关系的添加逻辑放在views.py的form_valid方法中,因为这里需要访问当前请求的用户、URL中的slug参数,这些都属于视图层的上下文数据,放在视图中更合理。
  • 表单简化:空表单足够触发提交流程,避免了不必要的字段渲染,符合你“除提交按钮外无其他界面元素”的需求。
  • 视图选型:用FormView替代原有的UpdateView,因为你不需要更新任何模型实例的字段,只是执行一个关联添加操作,FormView的语义更贴合这个场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 06:30:55