I have read a lot about how to add an extra field when using Django-registration, for example here, here and here. The code snippets are: forms.py (from the registration app)
class RegistrationForm(forms.Form):
username = forms.RegexField(regex=r'^\w+$', max_length=30, widget=forms.TextInput(attrs=attrs_dict), label=_("Username"), error_messages={ 'invalid': _("This value must contain only letters, numbers and underscores.") })
email = forms.EmailField(widget=forms.TextInput(attrs=dict(attrs_dict, maxlength=75)), label=_("Email"))
password1=forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), label=_("Password"))
institute=forms.CharField(max_length=50) #This is the new!
password2 = forms.CharField(widget=forms.PasswordInput(attrs=attrs_dict, render_value=False), label=_("Password (again)"))
captcha = CaptchaField()
I use the django's registration save method, which is in the default backend:
def register(self, request, **kwargs):
username, email, password = kwargs['username'], kwargs['email'], kwargs['password1']
if Site._meta.installed:
site = Site.objects.get_current()
else:
site = RequestSite(request)
new_user = RegistrationProfile.objects.create_inactive_user(username, email,
password, site)
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=request)
return new_user
In models.py I have created a new class:
class UserProfile(models.Model):
user = models.OneToOneField(User)
institute=models.CharField(max_length=50)
def create_user_profile(sender, instance, created, **kwargs):
if created:
profile, created = UserProfile.objects.get_or_create(user=instance)
post_save.connect(create_user_profile, sender=User)
In the admin.py:
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = UserProfile
class UserProfileAdmin(UserAdmin):
inlines = [ UserProfileInline, ]
admin.site.register(User, UserProfileAdmin)
I have not altered anything alse. When I render the form I can see the Institute Field I have added. When I am in the admin site I can see the user profile of each user. However nothing is saved there when I create a new user while the other details of the user are normally saved. I think that I need some kind of configuration but where? Maybe in the files of the Django-registration app?
required is often used to make the field optional that is the user would no longer be required to enter the data into that field and it will still be accepted.
Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField. Similarly, for other fields.
I have figured out a solution to this problem, and I will post it here in case somebody can use it. It's pretty simple, I suppose.
Step 1 Add a new model, which will be a profile, in the models.py:
#models.py
class user_profile(models.Model):
user=models.ForeignKey(User, unique=True)
institution=models.CharField(max_length=200)
def __unicode__(self):
return u'%s %s' % (self.user, self.institution)
Step 2 Create the form that will use this model:
#forms.py
from registration.forms import RegistrationForm
from django.forms import ModelForm
from Test.models import user_profile
class UserRegForm(RegistrationForm):
institution=forms.CharField(max_length=200)
Step 3 Create ragbackend.py and define how the data will be saved:
from Test.models import user_profile
from forms import *
def user_created(sender, user, request, **kwargs):
form = UserRegForm(request.POST)
data = user_profile(user=user)
data.institution = form.data["institution"]
data.save()
from registration.signals import user_registered
user_registered.connect(user_created)
Step 4 Go to urls.py and make the following changes:
import regbackend
from registration.views import register
url(r'^accounts/register/$', register, {'backend': 'registration.backends.default.DefaultBackend','form_class': UserRegForm}, name='registration_register'),
(r'^accounts/', include('registration.urls')),
Note that you have to put the URLs in that order. Easy to understand why.
Step 5 Now everything works, but you cannot see the information in the admin site. So you have to go to admin.py and add:
#admin.py
from django.contrib.auth.models import User
from Test.models import user_profile
admin.site.unregister(User)
class UserProfileInline(admin.StackedInline):
model = user_profile
class UserProfileAdmin(UserAdmin):
inlines = [ UserProfileInline, ]
admin.site.register(User, UserProfileAdmin)
And that's it. Do not forget the syncdb
before runserver
. I hope this will help someone.
In addition to Garrett's answer, I was getting a "cannot import name register" error with django-registration version 0.8. I believe this is because of class-based views, so update urls.py
accordingly:
from django.conf.urls import patterns, include, url
from registration.backends.default.views import RegistrationView
from abby.apps.accounts.forms import UserRegForm
urlpatterns = patterns('',
url(r'^register/$', RegistrationView.as_view(form_class=UserRegForm)),
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With