我正在尝试创建一个表单,以便用户可以将头像上传到他的个人资料。我有一个看起来像这样的类:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
picture = models.FileField(upload_to='media/images', blank=True, null=True)
现在我想访问picture
视图中的字段,以便我可以在其中放一些图片。我正在尝试这样做:
if request.method == 'POST':
userForm = SignupForm(request.POST, instance=user)
profileForm = ProfileForm(request.POST, request.FILES)
if userForm.is_valid():
...
user.profile.picture = request.POST['picture']
...
profileForm.save()
return HttpResponseRedirect('/')
...
,然后将其传递给模板。我在某处读到我可以通过模型中指定的related_name
访问此类字段,这就是我尝试过的。但是当我尝试上传图片时,它说:User has no profile.
我也读了很多关于get_profile()
功能的信息,但据我所知,它现在已经被剥夺了。
所以,请告诉我如何访问此字段?
也许我做错了?如果是,那么做这些事情的正确方法是什么?
你在这里错过了一个步骤。您需要检查用户和配置文件表单是否有效。然后,您需要保存用户窗体以获取 User 对象。然后,您需要创建配置文件对象,将其与用户关联并保存。
我不知道您为什么要单独设置个人资料图片 - 当然它应该是个人资料表单的一部分,并将与它一起保存。
这是我认为你感到困惑的地方:
userForm = SignupForm(request.POST, instance=user)
profileForm = ProfileForm(request.POST, request.FILES)
您同时使用两种不同的表单,但只验证第一种:
if userForm.is_valid():
你得到的是一个User has no profile.
,因为虽然用户存在,但配置文件不存在(无论如何在运行profileForm.save()
之前不会)。请记住,这是两种不同的模型。即便如此,你也做错了,原因有两个:
- 图片将驻留在
request.FILES
而不是request.POST
,因为它是一个文件 - 您正在尝试将图片分配给
user.profile.picture
- 但这毫无意义,因为您应该将其分配给配置文件,然后将该配置文件链接到用户(请记住,用户是配置文件模型上的字段)。当然,如果图片是表单的一部分,则无论如何都不需要这样做
。
所以,本质上,这个:
profileForm = ProfileForm(request.POST, request.FILES)
profileForm.instance.user = request.user #link the profile to current user
if profileForm.is_valid():
profileForm.save() #now you have a profile