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'
While the approach you have would work decently, there are a few things to consider.
For example, the database has 1000 student entries and 20 tutor entries. Now, there will be
In the
Usermodel, choosing to distinguish between a student and a tutor using the boolean fieldsis_studentandis_tutoris 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 calleduser_typeand have student and tutor as the possible options.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_studentandis_tutorin theUsermodel 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.If you were to display all the information in the
Usertable and theTutorProfiletable 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 inTutorProfileinside the response.A suggested workaround for this would be, assuming students and tutors are meant to be treated as mutually exclusive entities:
With this approach, there will be two models
StudentProfileandTutorProfilederived fromUser.To create an instance for a student, an object in
StudentProfilewill be created. Similarly, to create an instance for a tutor, an object inTutorProfilewill 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:
StudentProfiletable with all the fields of theUsermodel and all the additional fields in theStudentProfilemodel.TutorProfiletable with all the fields of theUsermodel and all the additional fields in theTutorProfilemodel, that is,bio.