user9092892
user9092892

Reputation:

Trying to extend AbstractUser to create multiple user types in Django

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)

Upvotes: 4

Views: 2391

Answers (2)

sytech
sytech

Reputation: 40861

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.

Upvotes: 3

Edwin Babu
Edwin Babu

Reputation: 719

add

class Meta:
    abstract = True

to profile model

and change AbstractUser to models.Model

Upvotes: 0

Related Questions