Django-Registration&Django-Profile,使用你自己的自定义表单

我正在使用django注册和djangoconfiguration文件来处理注册和configuration文件。 我想在注册时为用户创build一个configuration文件。 我已经创build了一个自定义registry单,并使用以下教程将其添加到了urls.py:

http://dewful.com/?p=70

本教程的基本思想是重写默认registry单以同时创buildconfiguration文件。

forms.py – 在我的个人资料的应用程序

from django import forms from registration.forms import RegistrationForm from django.utils.translation import ugettext_lazy as _ from profiles.models import UserProfile from registration.models import RegistrationProfile attrs_dict = { 'class': 'required' } class UserRegistrationForm(RegistrationForm): city = forms.CharField(widget=forms.TextInput(attrs=attrs_dict)) def save(self, profile_callback=None): new_user = RegistrationProfile.objects.create_inactive_user(username=self.cleaned_data['username'], password=self.cleaned_data['password1'], email=self.cleaned_data['email']) new_profile = UserProfile(user=new_user, city=self.cleaned_data['city']) new_profile.save() return new_user 

在urls.py中

 from profiles.forms import UserRegistrationForm 

 url(r'^register/$', register, {'backend': 'registration.backends.default.DefaultBackend', 'form_class' : UserRegistrationForm}, name='registration_register'), 

显示表格,我可以进入城市,但不保存或创build数据库中的条目。

你已经完成了一半 – 你已经成功地构build了一个自定义表单来replace默认表单。 但是你正试图在你的模型表单上使用save()方法进行自定义处理。 这在旧版本的django-registration中是可行的,但是我可以从你指定的URL conf中的后端指定你正在使用的v0.8。

升级指南说:

以前,注册期间用于收集数据的表单预计会执行save()方法,该方法将创build新的用户帐户。 这不再是这种情况; 创build帐户由后端处理,所以任何自定义逻辑都应该被移到自定义的后端,或者通过监听器连接注册过程中发送的信号。

换句话说,现在在版本0.8上,表单上的save()方法将被忽略。 您需要使用自定义后端或信号进行自定义处理。 我select了创build一个自定义的后端(如果任何人已经得到了这个信号的工作,请张贴代码 – 我不能以这种方式得到它)。 您应该可以修改这个以保存到您的自定义configuration文件。

  1. 在您的应用程序中创build一个regbackend.py。
  2. 从DefaultBackend复制register()方法到它。
  3. 在方法的最后,做一个查询来获取相应的User实例。
  4. 将附加的表单字段保存到该实例中。
  5. 修改URL conf,使其指向自定义表单和自定义后端

所以URL的conf是:

 url(r'^accounts/register/$', register, {'backend': 'accounts.regbackend.RegBackend','form_class':MM_RegistrationForm}, name='registration_register' ), 

regbackend.py具有必要的导入,基本上是DefaultBackend的一个副本,只有register()方法,并增加了:

  u = User.objects.get(username=new_user.username) u.first_name = kwargs['first_name'] u.last_name = kwargs['last_name'] u.save() 

正如我在Django Trac票上发表的评论中所描述的, 我制作了一个元类和一个mixin,以允许ModelForm Django表单的多重inheritance。 有了这个,你可以简单地创build一个表单,允许用户和configuration文件模型的字段同时注册,而不需要硬编码字段或重复自己。 通过使用我的元类和mixin(还有fieldset mixin),你可以做:

 class UserRegistrationForm(metaforms.FieldsetFormMixin, metaforms.ParentsIncludedModelFormMixin, UserCreationForm, UserProfileChangeForm): error_css_class = 'error' required_css_class = 'required' fieldset = UserCreationForm.fieldset + [( utils_text.capfirst(UserProfileChangeForm.Meta.model._meta.verbose_name), { 'fields': UserProfileChangeForm.base_fields.keys(), })] def save(self, commit=True): # We disable save method as registration backend module should take care of user and user # profile objects creation and we do not use this form for changing data assert False return None __metaclass__ = metaforms.ParentsIncludedModelFormMetaclass 

其中UserCreationForm可以为例如django.contrib.auth.forms.UserCreationForm窗体和UserProfileChangeForm简单的ModelForm为您的个人资料模型。 (不要忘记在User模型的外键中将editable设置为False 。)

用django注册后台有这样的注册方法:

 def register(self, request, **kwargs): user = super(ProfileBackend, self).register(request, **kwargs) profile, created = utils.get_profile_model().objects.get_or_create(user=user) # lambda-object to the rescue form = lambda: None form.cleaned_data = kwargs # First name, last name and e-mail address are stored in user object forms_models.construct_instance(form, user) user.save() # Other fields are stored in user profile object forms_models.construct_instance(form, profile) profile.save() return user 

注意注册信号是在这个方法的开始发送(在超类的方法中)而不是结束。

以同样的方式,您可以为用户和个人资料信息进行更改。 这个例子可以在我对上面提到的Django Trac票证的评论中find。

有信号的解决scheme – 在这里我写了如何使用信号来保存更多的数据

注册0.8和更高版本:

在您的views.py或同等版本中创buildregistration.backends.default.views.RegistrationView的子类:

 from registration.backends.default.views import RegistrationView class MyRegistrationView(RegistrationView): form_class= MyCustomRegistrationForm def register(self, request, **cleaned_data): new_user= super(MyRegistrationView, self).register(request, **cleaned_data) # here create your new UserProfile object return new_user