Django-Registration & Django-Profile using your own form

I use django-registration and django-profile for registration and profiles. I would like to create a profile for the user during registration. I created a special registration form and added it to urls.py using the tutorial on:

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

The main idea in the tutorial is to override the default registration form to create a profile at the same time.

forms.py - application in my profiles

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 

In urls.py

 from profiles.forms import UserRegistrationForm 

and

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

The form is displayed, and I can enter the City, however it does not save and does not create an entry in the database.

+31
python django django-forms registration profile
Apr 08 '10 at 16:05
source share
4 answers

You're halfway through - you've successfully created a custom form that replaces the default form. But you are trying to do your own processing using the save () method in your model form. This was possible in earlier versions of django registration, but I see that you specified a backend in your URL-conf that you use v0.8.

update guide says:

Previously, the form used to collect data during registration was expected to implement the save () method, which will create a new user account. This is no longer the case; the creation of the account is processed by the backend, and therefore any user logic must be switched to a user backend or connecting listeners to signals sent during the registration process.

In other words, the save () method on the form is ignored now that you are on version 0.8. You need to do your own processing either with a custom backend or with a signal. I decided to create a custom back-end (if someone got this working with signals, please send the code - I could not get it to work this way). You should be able to change this to save your custom profile.

  • Create regbackend.py in your application.
  • Copy the register () method from DefaultBackend into it.
  • At the end of the method, run the query to get the corresponding user instance.
  • Save the additional form fields in this instance.
  • Change the conf url to indicate BOTH user form and user back-end

So, the URL conf:

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

regbackend.py has the necessary import and is basically a copy of DefaultBackend using only the register () method and adding:

  u = User.objects.get(username=new_user.username) u.first_name = kwargs['first_name'] u.last_name = kwargs['last_name'] u.save() 
+29
Apr 22 2018-10-22T00:
source share

As described in my comment on the Django Trac ticket, I made a metaclass and mixin to allow multiple inheritance for Django ModelForm forms. With this, you can simply create a form that allows you to simultaneously register fields from user models and profiles without hardcoded fields or repeat yourself. Using my metaclass and mixin (as well as mixset mixin), you can:

 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 

Where UserCreationForm can be, for example, the form django.contrib.auth.forms.UserCreationForm and UserProfileChangeForm simple ModelForm for your profile model. (Remember to set editable to False in your foreign key for the User model.)

With a django registration database having this registration method:

 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 

Be careful that the registration signal is sent at the beginning of this method (in the method in the superclass), and not at the end.

In the same way, you can make a change form for both user information and the profile. An example of this can be found in my comment on the Django Trac ticket mentioned above.

+10
Jul 21 '10 at 11:01
source share

The solution with signals - here I wrote how to use signals to store additional data

+8
Jun 01 '10 at 5:59
source share

With registration 0.8 and later:

Subclass register.backends.default.views.RegistrationView in your views.py or equivalent:

 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 
+1
May 21 '14 at 11:35
source share



All Articles