pythondjangodjango-viewsdjango-formsdjango-registration

Django - How to run consecutive forms?


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]

EDIT

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!


Solution

  • 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