允许使用django-profiles更改用户字段(如电子邮件)

sha*_*ker 4 django django-models django-forms

Django允许您创建一个外键键入用户的模型,并在设置中将其定义为包含用户帐户附加数据的官方"配置文件"模型.django-profiles允许您轻松显示/创建/编辑该配置文件数据.但用户的主电子邮件地址是其主要帐户的一部分,而不是其扩展配置文件的一部分.所以当你放

{{ form }}
Run Code Online (Sandbox Code Playgroud)

在个人资料/ edit_profile模板中,主电子邮件地址不会显示.您可以使用手动检索它

{{ user.email }}
Run Code Online (Sandbox Code Playgroud)

但是当提交时,对它的更改不会保存回帐户.我假设已经创建了一个自定义ModelForm,例如:

class ProfileForm(ModelForm):

  class Meta:
      model = Parent
      exclude = ('family','user','board_pos','comm_job',)
Run Code Online (Sandbox Code Playgroud)

并且使用urlconf将ProfileForm传递给django-profiles的视图代码:

('^profiles/edit', 'profiles.views.edit_profile', {'form_class': ProfileForm,}),
Run Code Online (Sandbox Code Playgroud)

如果您想让用户更改他们的名字或姓氏,也会出现同样的问题.在使用django-profiles时,让用户更改自己的电子邮件地址或名称的最佳方法是什么?

sha*_*ker 8

这是我们最终使用的解决方案:

# urls.py
    # First match /profiles/edit before django-profiles gets it so we can pass in our custom form object.
    ('^profiles/edit', 'profiles.views.edit_profile', {'form_class': ProfileForm,}),
    (r'^profiles/', include('profiles.urls')),
Run Code Online (Sandbox Code Playgroud)

现在我们覆盖表单本身的save方法,这样在保存表单时,电子邮件地址会同时被推送到保存用户的User对象中.优美.

# forms.py , trimmed for brevity

class ProfileForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        try:
            self.fields['email'].initial = self.instance.user.email
        except User.DoesNotExist:
            pass

    email = forms.EmailField(label="Primary email")

    class Meta:
      model = Parent

    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.save()
      profile = super(ProfileForm, self).save(*args,**kwargs)
      return profile
Run Code Online (Sandbox Code Playgroud)

完美的工作.谢谢mandric.