1

I've done a lot of searching for this and even watched some tutorials, and most of them have different kinds of approach which makes me question myself if what I'm doing right now is correct. But I still tried to implement which I think is the best way base on what I learn in those tutorials, but I need some validation for this. This is what I did so far.

class User(AbstractUser):
    is_student = models.BooleanField(default=False)
    is_tutor = models.BooleanField(default=False)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    phone_number = models.CharField(max_length=11, blank=False, null=True)
    current_address = models.CharField(max_length=100, null=True)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')

class StudentProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    def __str__(self):
        return f'{self.user.username} Profile'

class TutorProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    bio = models.CharField(max_length=255, blank=True)
    def __str__(self):
        return f'{self.user.username} Profile'
  • hey, please explain what do you mean in `different profiles?`. – Shotiko Akhlouri Jul 29 '21 at 09:12
  • You mean you need a way to distinguish users by their profile type? – Ersain Jul 29 '21 at 11:28
  • It looks great. What's wrong with it? – Brian Destura Jul 29 '21 at 12:23
  • @ShotikoAkhlouri what I mean by that is I'd like to have some features found only on a tutor's profile like earnings, ratings or bio. The students also have their own profile but it's not the same as the tutor. sorry if I'm not being clear.. really new to this stuff.. – JustinAlvarez Jul 29 '21 at 13:34
  • @Ersain yeah I guess.. I mean I just wanna know if I've taken the right approach for creating a profile for multiple users. – JustinAlvarez Jul 29 '21 at 13:39
  • @bdbd Thank you. there's one thing I need to know and this is different from my question but I also registered the StudentProfile and TutorProfile in the admin.py along with the User.. did I do right? – JustinAlvarez Jul 29 '21 at 13:45

1 Answers1

1

While the approach you have would work decently, there are a few things to consider.

  1. While the current approach seems to be the appropriate use by having the common fields in one table, in the long run, there would be multiple entries in the database for both students and tutors .

For example, the database has 1000 student entries and 20 tutor entries. Now, there will be

  • 1020 entries in the User table,
  • 1000 entries in the StudentProfile table containing only the user id, and
  • 20 entries in the TutorProfile table containing the user id and bio.
  1. In the User model, choosing to distinguish between a student and a tutor using the boolean fields is_student and is_tutor is beneficial when a user can be both student and tutor at the same time. If they cannot be so, then it is better to keep a choice field called user_type and have student and tutor as the possible options.

  2. With separate models for student and tutor profiles, it can be queried which user is a student or a tutor. Hence, having the boolean fields is_student and is_tutor in the User model seems redundant. Also, if you choose to keep the boolean fields for the check, then to get all student data or all tutor data in the query set, the API will have to traverse through all the 1020 records to check the boolean field value and return it. This will significantly slow down the API and increase the time complexity.

  3. If you were to display all the information in the User table and the TutorProfile table for a user. The query would need to fetch all the data for the particular user associated to the tutor and then send that data along with the one in TutorProfile inside the response.

A suggested workaround for this would be, assuming students and tutors are meant to be treated as mutually exclusive entities:

class User(AbstractUser):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    phone_number = models.CharField(max_length=11, blank=False, null=True)
    current_address = models.CharField(max_length=100, null=True)
    image = models.ImageField(default='default.jpg', upload_to='profile_pics')

    def __str__(self):
        return f'{self.username} Profile'

class StudentProfile(User):
    pass

class TutorProfile(User):
    bio = models.CharField(max_length=255, blank=True)

With this approach, there will be two models StudentProfile and TutorProfile derived from User.

To create an instance for a student, an object in StudentProfile will be created. Similarly, to create an instance for a tutor, an object in TutorProfile will be created.

So to query either all students or all tutors, a GET request is hit to their respective model's API.

Continuing with the previous example,

In the database, for 1000 student entries and 20 tutor entries, now there will be:

  • 1000 entries in the StudentProfile table with all the fields of the User model and all the additional fields in the StudentProfile model.
  • 20 entries in the TutorProfile table with all the fields of the User model and all the additional fields in the TutorProfile model, that is, bio.
Tanya Jain
  • 361
  • 1
  • 9