4

So I have been searching all around the internet for a full example of how to user AbstractUser when u have at least 2 different models. Didn't find anything conclusive.. at least that would work on latest version of Django (2.0.1). I have 2 models, teacher and student, and registration needs to be different. Besides username, email, name and surname, I need for example, for the student, to upload a profile picture, email, phone, student_ID. And for teacher, bio, academic title and website. Did I start good ? What is the right approach ?

class Profile(AbstractUser): photo = models.ImageField(upload_to='students_images') email = models.EmailField() phone = models.CharField(max_length=15, ) class Student(Profile): student_ID = models.CharField(unique=True, max_length=14, validators=[RegexValidator(regex='^.{14}$', message='The ID needs to be 14 characters long.')]) def __str__(self): return self.name class Teacher(Profile): academic_title = models.CharField(max_length=30) bio = models.TextField() website = models.URLField(help_text="E.g.: https://www.example.com", blank=True)

6
  • 1
    You should not do that! You can only have one AUTH_USER_MODEL system-wide. Better use the default User as the user model and make Student and Teacher common models with a OneToOneField to User. You might wanna read these docs. In your case, extending is definitely better than substituting. Commented Jan 23, 2018 at 9:35
  • one way to do this is you can implement two signup form one for Student and another for Teacher using model form and then according to request you can render the right form in view. Commented Jan 23, 2018 at 9:36
  • @schwobaseggl I did that, but my users dont get saved as teachers or students. Here is my code: pastebin.com/syXh2Wn4 Commented Jan 23, 2018 at 10:24
  • @DannM You would have to manually populate the profile models in the form's save. The form doesn't do that because its model is User Commented Jan 23, 2018 at 10:27
  • @schwobaseggl can u show me how ? Commented Jan 23, 2018 at 10:42

2 Answers 2

3

Your goals can be accomplished using a 'Profile' pattern. You don't necessarily need to use a custom user model for this. But you need to have a single common model to for authentication; you can use the builtin django user for this or a custom class... Your Student and Teacher models should be OnetoOne relationships. This is the recommended solution per the documentation.

If you wish to store information related to User, you can use a OneToOneField to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.

In your case, you may do something like this:

class StudentProfile(models.Model): user = models.OneToOneField('User', related_name='student_profile') # additional fields for students class TeacherProfile(models.Model): user = models.OneToOneField('User', related_name='teacher_profile') # additional fields for teachers 

Then you can create your registration forms based on these profile models.

class StudentResistrationForm(forms.ModelForm): class Meta: model = StudentProfile fields = (...) class TeacherRegistrationForm(forms.ModelForm): class Meta: model = TeacherProfile fields = (...) 

You can create the user instance to which the profile is related to at the same time you create the profile. You might do this with formsets, for example.

Sign up to request clarification or add additional context in comments.

1 Comment

I will check this as best answer, tho I should have deleted this question long time ago. Found a simpler solution.
0

add

class Meta: abstract = True 

to profile model

and change AbstractUser to models.Model

1 Comment

Sorry, this is not what I need.