I have a user registration form that asks for user information and also asks a question: "Are you a PSMC member?"
The options are:
rank = [
('Supporter', 'Supporter (non-member)'),
('Anak', 'Anak'),
('Uso', 'Uso'),
('Chief', 'Chief'),
]
If Supporter
is selected, then the registration form proceeds and saves user info, etc. This part works fine. However, if Anak
is selected, I want it to take the user to another form that asks additional questions.
In my forms.py, I have class RegisterForm
which is the main registration form for all users. I also have class AnakRegisterForm
which is what I want it to continue on to. I used Django's AuthenticationForm based off what I read from their website (but I could be wrong). I know the issue is in views.py register
function. Specifically:
if rank == 'Anak':
anak_register(response)
During my debug session, after it moves response
to anak_register function, it gets a bunch of scrambled information. I'm pretty lost, any help would be appreciated. Here is my code:
forms.py
class RegisterForm(UserCreationForm):
email = forms.EmailField(
initial='',
required=True,
help_text='Please enter a valid email address'
)
rank = forms.ChoiceField(
label='Are you a PSMC member?',
choices=SavBlock.models.User.rank,
initial=False,
required=True,
help_text='Member accounts will be validated with your HC.'
)
class Meta:
model = User
# username = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
fields = ['username', 'first_name', 'last_name', 'email',
'rank', 'password1', 'password2']
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.ranking = self.cleaned_data['rank']
if commit:
user.save()
return user
class AnakRegisterForm(AuthenticationForm):
tribe = forms.ChoiceField(
label='What tribe are you from, Uce?',
choices=SavBlock.models.Anak.tribe,
initial=False,
required=True,
help_text='Member accounts will be validated with your HC.'
)
class Meta:
model = Anak
fields = ['tribe']
def save(self, commit=True):
user = super(AnakRegisterForm, self).save(commit=False)
user.tribe = self.cleaned_data['tribe']
if commit:
user.save()
return user
class UsoRegisterForm(AuthenticationForm):
pass
class ChiefRegisterForm(AuthenticationForm):
pass
views.py
def register(response):
context = {}
if response.method == "POST":
form = RegisterForm(response.POST)
if form.is_valid():
form.save()
rank = form.cleaned_data.get('rank')
if rank == 'Anak':
anak_register(response)
else:
form.save()
messages.success(response, 'Registration successful. Please login.')
return redirect('login')
else:
context['register'] = form
else:
form = RegisterForm()
context['register'] = form
return render(request=response, template_name='register/register.html', context={'form': form})
def anak_register(response):
# context = {}
if response.method == "POST":
form = AnakRegisterForm(response.POST)
if form.request.is_valid():
form.save()
messages.success(response, 'Registration successful. Please login.')
return redirect('login')
else:
'''
context['register'] = form
'''
else:
form = AnakRegisterForm()
# context['register'] = form
# messages.error(request, 'Unsuccessful registration. Invalid information.')
# form = RegisterForm
return render(request=response, template_name='register/register.html', context={'form': form})
models.py
class User(AbstractBaseUser, PermissionsMixin):
rank = [
('Supporter', 'Supporter (non-member)'),
('Anak', 'Anak'),
('Uso', 'Uso'),
('Chief', 'Chief'),
]
tribe = [
('NaKoaHema', 'Na Koa Hema'),
('Alakai', 'Alaka\'i')
]
username = models.CharField("user name", max_length=50, default='', unique=True)
email = models.EmailField("email address", max_length=30, unique=True, blank=True)
first_name = models.CharField("first name", max_length=50)
last_name = models.CharField("last name", max_length=50)
is_active = models.BooleanField('active', default=True)
# password = models.CharField("password", unique=True, max_length=32, default='')
id = models.AutoField(primary_key=True)
is_staff = models.BooleanField('staff status', default=False)
date_joined = models.DateField('date_joined', default=timezone.now)
ranking = models.CharField(choices=rank, max_length=50, default="Supporter")
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'password', 'ranking']
# Magic method returns string of self
def __str__(self):
return f"User {self.first_name} {self.last_name} rank {self.rank}".strip()
@property
def get_full_name(self):
return f"{self.first_name} {self.last_name}".strip()
class Anak(User):
def __init__(self, first_name, last_name, tribe):
super().__init__(first_name, last_name)
self.tribe = tribe.title()
self.rank = User.rank[1]
I changed AuthenticationForm to UserCreationForm and now it accepts the form. However, when I try to run it, I get the following error:
TypeError at /register/
__init__() missing 1 required positional argument: 'tribe'
If someone could point me in the right direction, I'd appreciate it!
Not sure how I missed this, but the best solution that I found is to implement Django Form Wizard. More information can be found here:
https://django-formtools.readthedocs.io/en/latest/wizard.html