Django-Registration & Django-Profile, Using Your Own Custom Form

Django-Registration & Django-Profile, using your own custom form

You're halfway there - you've successfully built a custom form that replaces the default form. But you're attempting to do your custom processing with a save() method on your model form. That was possible in older versions of django-registration, but I can see from the fact that you specified a backend in your URL conf that you're using v0.8.

The upgrade guide says:

Previously, the form used to collect
data during registration was expected
to implement a save() method which
would create the new user account.
This is no longer the case; creating
the account is handled by the backend,
and so any custom logic should be
moved into a custom backend, or by
connecting listeners to the signals
sent during the registration process.

In other words, the save() method on the form is being ignored now that you're on version 0.8. You need to do your custom processing either with a custom backend or with a signal. I chose to create a custom back-end (if anyone has gotten this working with signals, please post code - I wasn't able to get it working that way). You should be able to modify this to save to your custom profile.

  1. Create a regbackend.py in your app.
  2. Copy the register() method from DefaultBackend into it.
  3. At the end of the method, do a query to get the corresponding User instance.
  4. Save the additional form fields into that instance.
  5. Modify the URL conf so that it points to BOTH the custom form AND the custom back-end

So the URL conf is:

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

regbackend.py has the necessary imports and is basically a copy of DefaultBackend with just the register() method, and the addition of:

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

Creating a Django Registration Form by Extending Django-Registation Application

You are aware that the User model already has first_name and last_name fields, right? Also, you misstyped last_name to last_field.

I would advise to extend the form provided by django-registration and making a new form that adds your new fields. You can also save the first name and last name directly to the User model.

#get the form from django-registration
from registration.forms import RegistrationForm

class MyRegistrationForm(RegistrationForm):
first_name = models.CharField(max_length = 50, label=u'First Name')
last_field = models.CharField(max_length = 50, label=u'Last Name')
...
pincode = models.CharField(max_length = 15, label=u'Pincode')

def save(self, *args, **kwargs):
new_user = super(MyRegistrationForm, self).save(*args, **kwargs)

#put them on the User model instead of the profile and save the user
new_user.first_name = self.cleaned_data['first_name']
new_user.last_name = self.cleaned_data['last_name']
new_user.save()

#get the profile fields information
gender = self.cleaned_data['gender']
...
pincode = self.cleaned_data['pincode']

#create a new profile for this user with his information
UserProfile(user = new_user, gender = gender, ..., pincode = pincode).save()

#return the User model
return new_user

Registration form with profile's field

Setup

Are you using the django-profiles and django-registration projects? If not, you should—much of this code has already been written for you.

Profile

Your user profile code is:

class Profile(models.Model):
user = models.ForeignKey(User, unique=True)
born = models.DateTimeField('born to')
photo = models.ImageField(upload_to='profile_photo')

Have you correctly setup this profile in your Django settings? You should add this if not, substituting yourapp for your app's name:

AUTH_PROFILE_MODULE = "yourapp.Profile"

Registration Form

django-registration comes with some default registration forms but you specified you wanted to create your own. Each Django form field defaults to required so you should not need to change that. The important part is just making sure to handle the existing registration form fields and adding in the profile creation. Something like this should work:

from django import forms
from registration.forms import RegistrationForm
from yourapp.models import Profile
from registration.models import RegistrationProfile

class YourRegistrationForm(RegistrationForm):
born = forms.DateTimeField()
photo = forms.ImageField()

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 = Profile(user=new_user, born=self.cleaned_data['born'], photo=self.cleaned_data['photo'])
new_profile.save()
return new_user

Bringing it together

You can use the default django-registration templates and views, but will want to pass them your form in urls.py:

from registration.backends.default import DefaultBackend
from registration.views import activate
from registration.views import register

# ... the rest of your urls until you find somewhere you want to add ...

url(r'^register/$', register,
{'form_class' : YourRegistrationForm, 'backend': DefaultBackend},
name='registration_register'),

create profiles simultaneously with registration

change photo field in userProfile like this:

class userProfile(models.Model):    
name = models.CharField(max_length=30, default='')
user = models.OneToOneField(User)
photo = models.ImageField(blank=True,upload_to=url)
email = models.EmailField(max_length=75)

def __unicode__(self):
return self.user.username

This allow you to add userprofile without photo.

simply add userProfile when create new user like this:

def register_view(request):
form = RegisterForm()
if request.method == "POST":
form = RegisterForm(request.POST)
if form.is_valid():
first_name = form.cleaned_data['first_name']
usuario = form.cleaned_data['username']
email = form.cleaned_data['email']
password_one = form.cleaned_data['password_one']
password_two = form.cleaned_data['password_two']

u = User.objects.create_user(first_name=first_name,username=usuario,email=email,password=password_one)
u.save()

#add user profile
user_profile = userProfile(name=first_name,user=u,email=email)
user_profile.save()

return render_to_response('home/thanks_register.html',context_instance=RequestContext(request))
else:
ctx = {'form':form}
return render_to_response('home/register.html',ctx,context_instance=RequestContext(request))
ctx = {'form':form}
return render_to_response('home/register.html',ctx,context_instance=RequestContext(request))


Related Topics



Leave a reply



Submit