I have a Student model and a Teacher model and I have created a custom user form that takes in an email field and whether the user is a student or a teacher. I would like to make it so that if the user selects that they are a teacher in the sign-up form, their new account details are stored in the Teacher model. If they don't, then their details are stored in the Student model. Is this possible to do directly or do I have to store the data initially in the User model and then transfer it to the Student and Teacher models?
This is my code (I wasn't expecting it to work but I just tried it anyways and it didn't):
class CustomSignUpForm(UserCreationForm):
email = forms.EmailField()
is_teacher = forms.BooleanField(label='I am a teacher')
class Meta:
if is_teacher == True:
model = Teacher
else:
model = Student
fields = ['username', 'email', 'password1', 'password2', 'is_teacher']
CodePudding user response:
Yes, you should be able to do this by overriding the save()
Method.
Might need some tweaking, but this is generally what I'd do:
class CustomSignUpForm(UserCreationForm):
email = forms.EmailField()
is_teacher = forms.BooleanField(label='I am a teacher')
class Meta:
fields = ['username', 'email', 'password1', 'password2', 'is_teacher']
def save(self, commit=True):
# If you **Don't** want them to also be saved in the User's table, comment these lines out
user = super().save(commit=False)
if commit:
user.save()
# I'm doing get or create only on usernames,
# as I don't want changing the first name to create an entirely
# new object with a duplicate username
if self.cleaned_data.get('is_teacher'):
o = Teacher.objects.get_or_create(username=self.cleaned_data.get('username'))
else:
o = Student.objects.get_or_create(username=self.cleaned_data.get('username'))
# Manually set the fields
o.email = self.cleaned_data.get('email')
o.set_password(self.cleaned_data["password1"])
# Possibly not needed?- / Implied by table
# o.is_teacher = self.cleaned_data('is_teacher')
o.save()
return o
CodePudding user response:
I think you should consider separating the two sign up forms.
It's okay for there to be separate sign up forms, and even separate sign up views in the use case that an application has two very distinct user types.
This is especially prominent when you want to manage permissions with, for example, teacher vs student email addresses, as it is likely a teacher can see more than a student, and therefore that is your intention.
I cant write the answer for you, because there isnt enough contextual information, and doing so would promote questions that are too broad, however, I believe that if you create psuedo
:
class TeacherSignupView(...):
# configure the teacher sign ups
# use this view with the Teacher model
And then also in tandem, on another url:
class StudentSignupView(...):
# configure the student sign ups
Then it would be a trivial task to make specific behaviours for each user type.