I have a model called "Organization" that I've setup as a User profile and I would like to have the fields from the "Organization" model show up on the registration page. How do I go about doing this with django-registration.
# models.py
class Organization(models.Model):
user = models.ForeignKey(User, unique=True)
logo = models.ImageField(upload_to='organizations')
name = models.CharField(max_length=100, null=True, unique=True)
# more fields below etc.
# settings.py
AUTH_PROFILE_MODULE = 'volunteering.organization'
The easiest way to do this would be [tested on django-registration
0.8]:
Somewhere in your project, say forms.py in your organization app
from registration.forms import RegistrationForm
from django.forms import ModelForm
from models import Organization
class OrganizationForm(forms.ModelForm):
class Meta:
model = Organization
RegistrationForm.base_fields.update(OrganizationForm.base_fields)
class CustomRegistrationForm(RegistrationForm):
def save(self, profile_callback=None):
user = super(CustomRegistrationForm, self).save(profile_callback=None)
org, c = Organization.objects.get_or_create(user=user, \
logo=self.cleaned_data['logo'], \
name=self.cleaned_data['name'])
Then in your root urlconf [but above the regex pattern that includes registration.urls
and assuming that regex is r'^accounts/'
] add:
from organization.forms import CustomRegistrationForm
urlpatterns += patterns('',
(r'^accounts/register/$', 'registration.views.register', {'form_class':CustomRegistrationForm}),
)
Obviously, you can also create a custom backend, but IMHO this is way easier.
The best way would be to create in the app where you have Organization a file (say, "forms.py"), and do this:
from registration.forms import RegistrationForm
from forms import *
from models import Organization
class RegistrationFormWithOrganization(RegistrationForm):
organization_logo = field.ImageField()
organization_name = field.CharField()
def save(self, profile_callback = None):
Organization.objects.get_or_create(user = self.cleaned_data['user'],
logo = self.cleaned_data['organization_logo'],
name = self.cleaned_data['organization_name'])
super(RegistrationFormWithOrganization, self).save(self, profile_callback)
And then in your base URLs, override the existing URL to registration, and add this form as your the form to use:
form organization.forms import RegistrationFormWithOrganization
url('^/registration/register$', 'registration.views.register',
{'form_class': RegistrationFormWithOrganization}),
url('^/registration/', include('registration.urls')),
Remember that Django will use the first URL that matches the regexp, so will match your call and not django-registration's. It will also tell registration to use your form, not its own. I've skipped a lot of validation here (and, probably, the derivation of the user object... if so, go read the source code to registration to see where it comes from), but this is definitely the right track to get a few things into the page with a minimum amount of effort on your part.
Modify the code as below and try again
urlpatterns += patterns('',
(r'^accounts/register/$', 'registration.views.register', {'form_class':CustomRegistrationForm,'backend': 'registration.backends.default.DefaultBackend'}),
)
"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."
Details:
more info can be found here