我正在使用Django注册,和其他人不同的是,我似乎有相反的问题。我的User对象保存得很好,但我的UserProfile对象却不是!
我关注了这个网站:
http://birdhouse.org/blog/2009/06/27/django-profiles/这真的很好,所以现在我有了:
class ProfileForm(forms.ModelForm):
YESNO = [
(True,mark_safe('<img src="/static_files/greenTick.png"/>')),
(False,mark_safe('<img src="/static_files/redCross.png"/>'))]
class Meta:
model = UserProfile
exclude = ('isTweeting','points','user')
fields = ('display_name','first_name','last_name','email','gravatar')
def __init__(self, *args, **kwargs):
super(ProfileForm, self).__init__(*args, **kwargs)
self.fields['email'].initial = self.instance.user.email
self.fields['first_name'].initial = self.instance.user.first_name
self.fields['last_name'].initial = self.instance.user.last_name
self.fields['display_name'].initial = self.instance.user.username
self.fields['gravatar'].initial = self.instance.usesGravatar
#add in the input to size it juuuuust right.
email = forms.EmailField(label="Primary email",help_text='',widget=forms.TextInput(attrs={'class': 'wideInput'}))
first_name = forms.Field(label="First name",help_text='',required=False,widget=forms.TextInput(attrs={'class': 'wideInput'}))
last_name = forms.Field(label="Last name",help_text='',required=False,widget=forms.TextInput(attrs={'class': 'wideInput'}))
display_name = forms.Field(label="Display name",help_text='',widget=forms.TextInput(attrs={'class': 'wideInput'}))
gravatar = ImgModelChoiceField(label='Gravatar', choices=YESNO, widget=forms.RadioSelect(renderer=ImgRadioFieldRenderer))
def save(self, *args, **kwargs):
"""
Update the primary email address on the related User object as well.
"""
u = self.instance.user
u.email = self.cleaned_data['email']
u.username = self.cleaned_data['display_name']
u.first_name = self.cleaned_data['first_name']
u.last_name = self.cleaned_data['last_name']
u.save()
self.instance.gravatar = (self.cleaned_data['gravatar'] == 'True')
profile = super(ProfileForm, self).save(*args,**kwargs)
return profile此对象作为form_class传递到Django-profile中以供使用,如上面的网站所述。我的问题是,当我提交我的表单时,虽然“用户”数据被正确地更新了--电子邮件中的任何更改或其他东西传播到数据库--对"gravatar“值的更改不会被发送。也不会抛出错误。
你知道我该怎么做吗?
发布于 2012-07-06 18:56:04
我想在这里冒险猜一猜
def save(self, *args, **kwargs):
...
self.instance.gravatar = (self.cleaned_data['gravatar'] == 'True')
profile = super(ProfileForm, self).save(*args,**kwargs)
return profile您似乎正在使用一个自定义小部件,根据外观,在将字符串'True' (从表单传回)保存到DB之前,您需要将其更改为布尔True。但是,当您在下一行调用save()时,ModelForm将用直接来自表单cleaned_data的数据覆盖您提供给self.instance.gravatar的值
https://github.com/django/django/blob/master/django/forms/models.py#L351
此外,在__init__中,您不需要包含
self.fields['gravatar'].initial = self.instance.usesGravatar因为这个字段已经绑定到模型表单,并且将在视图中实例化表单和实例时自动填充(例如,如果正在编辑UserProfile )。
最后,在您的Meta中,不需要同时包含excludes和fields,其中之一就可以了。
发布于 2012-07-07 13:30:03
首先,考虑@Timmy的建议。唯一需要注意的是这一行:
profile = super(ProfileForm, self).save(*args,**kwargs)默认情况下,save方法具有commit=True。验证调用此表单的函数是否正在以args或kwargs格式发送commit=False。如果是,则必须在返回之前手动保存配置文件profile.save(),因为commit=False意味着更改不会反映到数据库。
为什么您允许用户同时更新用户名和电子邮件?如果允许同时更新两个字段,您将如何跟踪注册过程?通常用户使用他们的电子邮件注册。定义您希望保持哪个字段(用户名或电子邮件)不变的条件。
更新
另外,您在save函数中还做了一件错误的事情。您正在更新从instance.user获取的用户的电子邮件、用户名、名字和姓氏。但是,当配置文件表单默认保存被称为profile = super(ProfileForm, self).save(*args,**kwargs)时,该实例将被覆盖。您应该做的是使用由super返回的user = profile.user即profile来更新这些字段。您的save函数应该如下所示:
def save(self, *args, **kwargs):
"""
Update the primary email address on the related User object as well.
"""
profile = super(ProfileForm, self).save(*args,**kwargs)
u = profile.user
u.email = self.cleaned_data['email']
u.username = self.cleaned_data['display_name']
u.first_name = self.cleaned_data['first_name']
u.last_name = self.cleaned_data['last_name']
u.save()
#profile.save() #if commit=False in kwargs
return profilehttps://stackoverflow.com/questions/11254464
复制相似问题