Django 1.11.8报错:'User' object is not iterable,多对多字段赋值问题
解决Django中
'User' object is not iterable报错问题 嘿,我来帮你搞定这个问题!你碰到的'User' object is not iterable错误,本质是错误地给ManyToMany类型字段直接赋值单个User对象导致的——咱们一步步拆解原因和解决方案:
错误根源分析
你的Choice模型里users是ManyToManyField(User),这表示一个Choice可以关联多个用户,一个用户也能关联多个Choice。而你在代码里写了:
model_conn.users = user_v
这种直接赋值的方式只适用于ForeignKey(一对多/一对一)字段,对ManyToMany字段不适用——它需要接收一个可迭代的对象集合(比如列表、QuerySet),而不是单个User实例,所以才会抛出“对象不可迭代”的错误。
修复方案
对于ManyToMany字段,要添加关联对象,得用它的add()方法,而不是直接赋值。同时咱们还可以优化一下代码逻辑,减少不必要的循环:
修改后的views.py代码
from django.shortcuts import render from django.contrib.auth.decorators import login_required from .models import Choice @login_required def index(request): if request.method == 'POST': # 先判断是否是POST请求,避免GET请求时出错 food = request.POST.get('sunday') if food: try: # 直接根据提交的choice值获取对应的模型实例,不用遍历所有Choice model_conn = Choice.objects.get(choices=food) # 投票数+1 model_conn.vote += 1 model_conn.save() # 添加当前用户到关联的users字段,先检查是否已关联避免重复添加 if not model_conn.users.filter(id=request.user.id).exists(): model_conn.users.add(request.user) except Choice.DoesNotExist: # 处理提交的choice不存在的情况 pass # 获取所有选项数据传给模板 get_choices = Choice.objects.values('choices', 'vote') return render(request, 'index.html', {'choices': get_choices})
关键修改点
- 替换
model_conn.users = user_v为model_conn.users.add(request.user):这是ManyToMany字段添加关联对象的正确方式 - 增加
request.method == 'POST'判断:避免GET请求时执行投票逻辑,更符合HTTP规范 - 直接通过
Choice.objects.get(choices=food)获取目标实例:省去遍历所有Choice的冗余操作 - 添加用户存在性检查:防止同一用户重复关联同一个Choice(根据你的业务需求,若允许重复则可以去掉这步)
- 移除多余的
user_v变量和is_authenticated()判断:因为@login_required装饰器已经确保用户是登录状态,无需再判断
额外提醒
在Django 1.11中,request.user.is_authenticated()是正确的方法调用,但在Django 2.0及以后版本中它变成了属性(request.user.is_authenticated),不过你用1.11版本的话不用改这点。
内容的提问来源于stack exchange,提问作者Dhaval Savalia
相关产品推荐
相关产品推荐

