Как описано в моем комментарии к билету Django Trac Я создал метакласс и миксин, чтобы разрешить множественное наследование ModelForm
форм Django. При этом вы можете просто создать форму, которая позволяет одновременно регистрировать поля из пользовательских и профильных моделей без жесткого кодирования полей или повторения. Используя мой метакласс и миксин (а также миксин fieldset) вы можете сделать:
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
для вашей модели профиля. (Не забудьте установить editable
на False
в вашем внешнем ключе на User
модель.)
С бэкэндом 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, упомянутому выше.