0

我为此做了很多搜索,甚至观看了一些教程,其中大多数都有不同类型的方法,这让我质疑自己现在所做的是否正确。但是我仍然尝试根据我在这些教程中学到的知识来实现​​我认为是最好的方法,但我需要对此进行一些验证。这就是我到目前为止所做的。

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'
4

1 回答 1

0

虽然您采用的方法可以正常工作,但仍有一些事项需要考虑。

  1. 虽然当前的方法似乎是通过将公共字段放在一个表中来适当使用,但从长远来看,数据库中将有多个学生和导师的条目。

例如,数据库有 1000 个学生条目和 20 个导师条目。现在,会有

  • 用户表中有 1020 个条目,
  • StudentProfile 表中的 1000 个条目仅包含用户 ID,并且
  • TutorProfile 表中有 20 个条目,包含用户 ID 和简历。
  1. User模型中,选择使用布尔字段来区分学生和导师,is_student并且is_tutor当用户可以同时是学生和导师时是有益的。如果他们不能这样,那么最好保留一个选择字段user_type,并让学生和导师作为可能的选项。

  2. 通过学生和导师档案的单独模型,可以查询哪个用户是学生或导师。因此,在模型中包含布尔字段is_student和似乎是多余的。此外,如果您选择保留布尔字段进行检查,那么要获取查询集中的所有学生数据或所有导师数据,API 将不得不遍历所有 1020 条记录以检查布尔字段值并返回它。这将显着减慢 API 并增加时间复杂度。is_tutorUser

  3. 如果您要显示表中的所有信息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)

使用这种方法,将有两个模型StudentProfileTutorProfileUser.

要为学生创建实例,StudentProfile将创建一个对象。类似地,要为导师创建实例,将创建一个对象TutorProfile

因此,要查询所有学生或所有导师,需要向他们各自模型的 API 发出 GET 请求。

继续前面的例子,

在数据库中,对于 1000 个学生条目和 20 个导师条目,现在将有:

  • 表中的 1000 个条目,包含模型的所有StudentProfile字段和User模型中的所有附加字段StudentProfile
  • 表中的 20 个条目,包含模型TutorProfile的所有字段以及User模型中的所有附加字段TutorProfile,即bio.
于 2021-07-29T16:41:49.773 回答