While the approach you have would work decently, there are a few things to consider.
- 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.
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.
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.
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
.