多对多字段误添加全部用户而非投票用户的问题求助
问题分析与解决方案
看起来你遇到的问题是所有用户都被莫名添加到了Question的users字段中,而非仅完成投票的用户。这大概率是因为你的subscribe方法定义和调用逻辑存在偏差,导致代码执行不符合预期。
问题根源拆解
先看你写的subscribe方法:
def subscribe(cls, current_user, new_vote): new_vote.users.add(current_user)
这里有两个核心问题:
- 你试图写类方法却没加
@classmethod装饰器,导致参数传递完全混乱。当你调用Question.subscribe(request.user, question)时,cls实际接收的是request.user,current_user接收的是question,而new_vote参数根本没被传入——正常来说这会直接报错,除非你还有其他错误逻辑干扰了执行。 - 就算忽略装饰器问题,调用时的参数顺序也完全颠倒了:方法定义的参数顺序是
(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ı
相关产品推荐
相关产品推荐

