Django项目更新User模型布尔字段报错:'bool'对象无对应属性
'bool' object has no attribute 'has_created_artist_profile'错误 我正在开发一个Django项目,已编写存储用户详情的Artist模型。用户注册后需完善该自定义资料,我在User模型中设置了布尔字段has_created_artist_profile,用于标记用户是否已完成资料填写,方便在模板中做逻辑处理。
但提交资料表单时,尝试将该布尔字段从False更新为True时出现报错:
'bool' object has no attribute 'has_created_artist_profile'
相关代码如下:
views.py
def ArtistEditView(request): artist = Artist.objects.get(user=request.user) current_artist = request.user artist_status = current_artist.has_created_artist_profile if request.method == 'POST': form = ArtistForm(request.POST, request.FILES, instance=artist) if form.is_valid(): artist_status.has_created_artist_profile = True artist_status.save() form.save() return redirect(reverse('artist_home')) else: artist_dict = model_to_dict(artist) form = ArtistForm(artist_dict) return render(request, 'artist/artist_edit.html', {'form': form})
forms.py
class ArtistForm(forms.ModelForm): class Meta: model = Artist exclude =['user', ]
错误原因分析
你这里的问题很清晰:artist_status = current_artist.has_created_artist_profile这一行,你把User实例的布尔字段值(True或False)赋值给了artist_status变量。然后你试图去修改artist_status.has_created_artist_profile——但artist_status本身就是个布尔值,它根本没有这个属性,自然会报错。
方案1:直接操作User实例修正视图
修改视图里的POST处理逻辑,直接对request.user这个User实例进行字段修改,而不是先把字段值取出来:
def ArtistEditView(request): artist = Artist.objects.get(user=request.user) # 不需要单独定义current_artist和artist_status,直接用request.user即可 if request.method == 'POST': form = ArtistForm(request.POST, request.FILES, instance=artist) if form.is_valid(): # 直接修改User实例的布尔字段 request.user.has_created_artist_profile = True request.user.save() form.save() return redirect(reverse('artist_home')) else: # 这里可以直接用instance初始化表单,不用转字典,更简洁可靠 form = ArtistForm(instance=artist) return render(request, 'artist/artist_edit.html', {'form': form})
方案2:通过信号自动更新(更解耦的写法)
如果你的Artist和User是一对一关联的,推荐用Django的信号机制,在Artist保存时自动更新User的字段状态。这样视图里不用额外写更新代码,逻辑更清晰:
在你的models.py里添加信号接收器:
from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver class Artist(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 你的其他字段... # 监听Artist的保存事件 @receiver(post_save, sender=Artist) def update_user_profile_status(sender, instance, **kwargs): # 只要Artist被保存(新建或更新),就把用户的资料完成状态设为True if not instance.user.has_created_artist_profile: instance.user.has_created_artist_profile = True instance.user.save()
这样一来,不管是用户第一次创建Artist资料,还是后续编辑,User的has_created_artist_profile都会自动被设为True,视图里只需要处理表单保存即可。
额外小建议
- 给
User模型的has_created_artist_profile字段设置默认值False,这样用户注册时就自动拥有这个初始状态,不用手动处理:has_created_artist_profile = models.BooleanField(default=False) - 初始化表单时直接使用
instance=artist,比model_to_dict更符合Django的最佳实践,也能避免一些字段类型转换的问题。
内容的提问来源于stack exchange,提问作者Adam Dalton

