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.
- Create a regbackend.py in your app.
- Copy the register() method from DefaultBackend into it.
- At the end of the method, do a query to get the corresponding User instance.
- Save the additional form fields into that instance.
- 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
How to Add a Question Mark [] Button on the Top of a Tkinter Window
Numpy.Where() Detailed, Step-By-Step Explanation/Examples
String Comparison Doesn't Seem to Work for Lines Read from a File
Rect Collision with List of Rects
Flask Importerror: No Module Named Flask
Remove None Value from a List Without Removing the 0 Value
In Python, How to Test If I'm in Google App Engine Sdk
How to Switch Columns Rows in a Pandas Dataframe
How to Get All of the Output from My .Exe Using Subprocess and Popen
Validation of a Password - Python
Python Integer Incrementing with ++
Directing Print Output to a .Txt File
Create a Main Loop with Tkinter
How to Merge Two Lists into a Single List