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

多对多字段误添加全部用户而非投票用户的问题求助

问题分析与解决方案

看起来你遇到的问题是所有用户都被莫名添加到了Question的users字段中,而非仅完成投票的用户。这大概率是因为你的subscribe方法定义和调用逻辑存在偏差,导致代码执行不符合预期。

问题根源拆解

先看你写的subscribe方法:

def subscribe(cls, current_user, new_vote):
    new_vote.users.add(current_user)

这里有两个核心问题:

  1. 你试图写类方法却没加@classmethod装饰器,导致参数传递完全混乱。当你调用Question.subscribe(request.user, question)时,cls实际接收的是request.user,current_user接收的是question,而new_vote参数根本没被传入——正常来说这会直接报错,除非你还有其他错误逻辑干扰了执行。
  2. 就算忽略装饰器问题,调用时的参数顺序也完全颠倒了:方法定义的参数顺序是(cls, current_user, new_vote),但你调用时传的是(request.user, question),完全不符合方法的预期逻辑。

正确的实现方案

我推荐把subscribe改成实例方法,因为它本质是针对某一个具体的Question实例添加投票用户,逻辑更直观清晰:

修正后的模型代码

from django.contrib.auth.models import User
from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    choice_number = models.IntegerField(default=2)
    category = models.CharField(max_length=50, default="comparison")
    users = models.ManyToManyField(User, blank=True)

    # 改成实例方法,直接操作当前Question实例的users字段
    def subscribe(self, current_user):
        # ManyToManyField的add方法是幂等的,重复调用不会重复添加同一用户
        self.users.add(current_user)

修正后的视图代码

def change_vote(request, instruction, pk):
    question = Question.objects.get(pk=pk)
    # 用question实例直接调用subscribe,传入当前投票的用户
    question.subscribe(request.user)
    # 无需额外调用save(),ManyToMany的add操作会自动同步到数据库
    
    # 后续的视图逻辑(比如重定向到投票结果页等)
    # ...

额外排查点

如果修正后还是出现所有用户被添加的情况,你需要检查:

  • 是否在其他视图、信号或管理后台操作中,不小心执行了类似question.users.add(*User.objects.all())的代码,批量添加了所有用户。
  • 检查管理后台的Question编辑页面,是否误操作勾选了所有用户并保存。

这样调整后,只有完成投票的用户会被添加到对应Question的users字段中,不会再出现批量添加的问题。

内容的提问来源于stack exchange,提问作者İbrahim Hakkı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 00:02:41