问题描述
我为此进行了大量搜索,甚至观看了一些教程,其中大多数都有不同类型的方法,这让我怀疑自己现在所做的是否正确。但是我仍然尝试根据我在这些教程中学到的知识来实现我认为最好的方法,但是我需要对此进行一些验证。这就是我目前所做的。
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'
解决方法
虽然您采用的方法效果不错,但仍有一些事项需要考虑。
- 虽然当前的方法似乎是将公共字段放在一张表中的合适用途,但从长远来看,数据库中将有多个条目供学生和导师使用。
例如,数据库有 1000 个学生条目和 20 个导师条目。 现在,将有
- 用户表中有 1020 个条目,
- StudentProfile 表中仅包含用户 ID 的 1000 个条目,以及
- TutorProfile 表中的 20 个条目,其中包含用户 ID 和个人简介。
-
在
User
模型中,当用户既可以是学生又可以是导师时,选择使用布尔字段is_student
和is_tutor
来区分学生和导师是有益的同时。如果不能,那么最好保留一个名为user_type
的选择字段,并让学生和导师作为可能的选项。 -
使用单独的学生和导师档案模型,可以查询哪个用户是学生或导师。因此,在
is_student
模型中包含布尔字段is_tutor
和User
似乎是多余的。此外,如果您选择保留布尔字段进行检查,那么要获取查询集中的所有学生数据或所有导师数据,API 将必须遍历所有 1020 条记录以检查布尔字段值并将其返回。这将显着降低 API 的速度并增加时间复杂度。 -
如果您要为用户显示
User
表和TutorProfile
表中的所有信息。该查询需要获取与导师关联的特定用户的所有数据,然后将该数据与响应中的TutorProfile
中的数据一起发送。
建议的解决方法是,假设学生和导师被视为相互排斥的实体:
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)
采用这种方法,将有两个模型 StudentProfile
和 TutorProfile
派生自 User
。
要为学生创建实例,将在 StudentProfile
中创建一个对象。同样,要为导师创建实例,将在 TutorProfile
中创建一个对象。
因此,要查询所有学生或所有导师,请向其各自模型的 API 发出 GET 请求。
继续前面的例子,
在数据库中,对于 1000 个学生条目和 20 个导师条目,现在将有:
-
StudentProfile
表中有 1000 个条目,其中包含User
模型的所有字段和StudentProfile
模型的所有附加字段。 -
TutorProfile
表中的 20 个条目,包含User
模型的所有字段以及TutorProfile
模型的所有附加字段,即bio
。立>