I'm trying to setup django-registration form with an extra field or two. I've read the documentation and scoured StackOverflow. I'm getting a problem where the user is registered with the new fields but when I try and login it doesn't recognise the password.
I've created a new view (I've just cut and pasted register from django-registration because I just want it running initially):
class MyRegistrationView (RegistrationView):
form_class = UserRegForm
def register(self, form):
new_user = RegistrationProfile.objects.create_inactive_user(
form,
site=get_current_site(self.request)
)
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
return new_user
It uses this form:
class UserRegForm(RegistrationForm):
CHOICES = Institution.objects.all().order_by('name')
institution=forms.ChoiceField(choices=( (x.id, x.name) for x in CHOICES ),
required = True)
These are the additional models:
class Institution(models.Model):
name = models.CharField(max_length=200)
def __unicode__(self):
return u'%s' % (self.name)
class UserProfile(models.Model):
user=models.OneToOneField(User, on_delete=models.CASCADE)
institution=models.ForeignKey(
Institution,
null=True,
blank=True)
def __unicode__(self):
return u'%s' % (self.user)
My URL
url(r'^register', views.MyRegistrationView.as_view(form_class=UserRegForm), name='registration_register'),
And I've added this to save the data: from models import UserProfile from forms import UserRegForm
def user_created(sender, user, request, **kwargs):
form = UserRegForm(request.POST)
try: data = UserProfile.objects.get(user=user)
except: data = UserProfile(user=user)
data.institution = form.data["institution"]
data.save()
from registration.signals import user_registered
user_registered.connect(user_created)
Everything works in that the user is registered, an email is sent out, the institution is saved to the UserProfile, but when I try and login using the new user (having activated the account) it tells me the username and password don't match.
When I look at the database the hashed paasword string seems to be 10 characters shorter than the admins (setup using manage.py createsuperuser) so I am doing something I shouldn't or not doing something I should.
Help would be much appreciated.
I solved this by basically copying all of RegistrationView into MyRegistrationView. The login now works are well. I'm not sure why this was necessary.
from registration.backends.model_activation.views import RegistrationView
from registration.models import RegistrationProfile
from registration import signals
from django.contrib.sites.shortcuts import get_current_site
from django.core import signing
from django.template.loader import render_to_string
from django.conf import settings
REGISTRATION_SALT = getattr(settings, 'REGISTRATION_SALT', 'registration')
class MyRegistrationView (RegistrationView):
form_class = UserRegForm
email_body_template = 'registration/activation_email.txt'
email_subject_template = 'registration/activation_email_subject.txt'
def register(self, form):
new_user = self.create_inactive_user(form)
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=self.request)
return new_user
def get_success_url(self, user):
return ('registration_complete', (), {})
def create_inactive_user(self, form):
"""
Create the inactive user account and send an email containing
activation instructions.
"""
new_user = form.save(commit=False)
new_user.is_active = False
new_user.save()
self.send_activation_email(new_user)
return new_user
def get_activation_key(self, user):
"""
Generate the activation key which will be emailed to the user.
"""
return signing.dumps(
obj=getattr(user, user.USERNAME_FIELD),
salt=REGISTRATION_SALT
)
def get_email_context(self, activation_key):
"""
Build the template context used for the activation email.
"""
return {
'activation_key': activation_key,
'expiration_days': settings.ACCOUNT_ACTIVATION_DAYS,
'site': get_current_site(self.request)
}
def send_activation_email(self, user):
"""
Send the activation email. The activation key is simply the
username, signed using TimestampSigner.
"""
activation_key = self.get_activation_key(user)
context = self.get_email_context(activation_key)
context.update({
'user': user
})
subject = render_to_string(self.email_subject_template,
context)
# Force subject to a single line to avoid header-injection
# issues.
subject = ''.join(subject.splitlines())
message = render_to_string(self.email_body_template,
context)
user.email_user(subject, message, settings.DEFAULT_FROM_EMAIL)
Remaining issue is it just reloads the Registration page rather than going to registration complete?