Reputation: 51
I have created a CustomUser
model and it has a one to relationship with my two other models.
class User(AbstractUser):
is_learner = models.BooleanField(default=False)
is_teacher = models.BooleanField(default=False)
class Teacher(models.Model):
#teacher_name = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True)
class Learner(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, primary_key=True)
They do not show up when I try to create learner and teacher objects in their respective databases, as shown:
class LearnerSignUpForm(UserCreationForm):
email = forms.EmailField()
class Meta(UserCreationForm.Meta):
#User = CustomUser
model = CustomUser
fields = ["username", "email", "password1", "password2"]
#fields = UserCreationForm.Meta.fields + ("username", "email", "password1", "password2")
@transaction.atomic
def save(self, *args, **kwargs):
user = super().save(commit=False)
user.is_learner = True
user.save()
learner = Learner.objects.create(user=user)
return user
How do I get it to save in learner and teacher tables respectively?
Upvotes: 0
Views: 183
Reputation: 1711
Welcome to StackOverflow!
It is worth pointing that using model.objects.create(...)
you're implicitly telling Django that you want to create the object with the specific values you give and save it. check the docs page here
If you wish to save an object for which has associated items, you can create a form and use a ModelChoiceField
and provide the model and default choices using the choices
kwarg. An example of a choices value would be YourUserModel.objects.all()
However, I think in your case you may not want to give the user the freedome to make this choice, in which it would be correct to override the save()
method of your form and create the intended logic.
Secondly, I have used Django for quite some time and never seen a Model.Meta
class used in this way so forgive me if I'm mistaken, but I also think you need have your save()
method directly on your LearnerSignupForm
and not on the Meta
class.
Thirdly, if you setup your forms correctly, using the correct types of fields, Django forms will deal with all the messy stuff for you and complain at you when you do something wrong (usually gracefully).
Lastly, I would highly recommend having a read through the docs page for creating new objects
Free code:
class LearnerSignUpForm(UserCreationForm):
email = forms.EmailField()
class Meta(UserCreationForm.Meta):
model = CustomUser
fields = ["username", "email", "password1", "password2"]
@transaction.atomic
def save(self, *args, **kwargs):
user = super().save(commit=False)
user.is_learner = True
# create the relationship between the user and learner
learner = user.learner_set.create(user=user)
# user.learner_set.add(learner) # usually this way with FK
user.save()
return user # should this return the Learner object?
One final bit of advice:
Try to make your code as readable as possible! There's no reason that code can't be functional and beautiful! And where possible, you should make you class names and variable names as appropriate as possible, I would for example maybe use Student
instead of Learner
Upvotes: 1