【问题标题】:Check user account model type检查用户帐户模型类型
【发布时间】:2014-06-19 12:05:33
【问题描述】:

检查已扩展 Django 用户模型的帐户的模型类型的最佳方法是什么? 我有两种扩展 django 用户模型的用户帐户(学生和教师,比如说):

class Student(models.Model):
     student_bd = models.CharField(max_length=50)
     student_user = models.ForeignKey(User)
     ...

class Teacher(models.Model):
     teacher_bd = models.CharField(max_length=50)
     teacher_user = models.ForeignKey(User)
     ...

那么,我怎么知道 request.user 是 Student 还是 Teacher?

【问题讨论】:

  • isinstance(request.user,Student) ?
  • 这行不通,因为 request.user 始终是 User 实例。
  • 这就是我对子类进行测试的原因

标签: django django-users


【解决方案1】:

User 表中没有保存关于Student 和Teacher 模型的数据,因此您必须查询相关对象。

如果您不需要实际的配置文件(Student 或Teacher 对象),最快的方法是使用相关集上的exists() 函数:

if request.user.student_set.exists():
    # student
elif request.user.teacher_set.exists():
    # teacher

如果您知道稍后将需要配置文件对象,那么在 Python 中获取结果并检查现有对象会更快:

if request.user.student_set.all():
    # do something with student_set
elif request.user.teacher_set.all():
    # do something with teacher_set

旁注: 如果您的用户不应该拥有多个Student 或Teacher 相关对象,那么使用OneToOneField 而不是ForeignKey 可能是一个更好的主意。这样,您就不必为all() 等而烦恼,但您可以使用user.student 或user.teacher 访问相关的模型实例。这也将允许您使用select_related,以便在单个查询中获取用户对象和学生或教师对象。

【讨论】:

  • 赞,不知道你可以这样浏览相关对象。让我的答案看起来……很简陋。来自我的 +1。
  • @knbk,感谢您的彻底回答和旁注。 Eduardo 首先回答,所以我必须接受他的回答是正确的。顺便说一句,我不知道为什么,但 Django 说'User' object has no attribute 'student_set'。
  • @LjubisaLivac 您使用的是哪个版本的 Django?默认名称可能不同,但您始终可以指定相关名称:student_user = models.ForeignKey(User, related_name='students')。我总是指定一个相关的名称,因为它可以避免很多混乱。
【解决方案2】:

如果您有一个 User 模型并想检查该模型是否对应于 Teacher 或 Student 模型,则需要从每个表中获取相应的行:

try:
    Student.objects.get(student_user=request.user)
    is_student = True
except Student.DoesNotExist:
    is_student = False

老师也一样。 is_student 和 is_teacher 将分别告诉您 User 是 Student 还是 Teacher。如果用户同时是学生和教师,这也适用于奇怪的情况:) 在这种情况下没有用,但认为它有助于学校中的其他角色。

【讨论】:

  • 在你问之前,不,不查询数据库是没有办法的。
  • 谢谢你的回答,你帮助了我。这就是我所做的:Student.objects.filter(student_id=user.id).first() - 它返回对象或无。
  • @LjubisaLivac 请修改您的代码,因为它会产生错误的结果。您可以按照自己的方式进行操作,但只需稍作改动:Student.objects.filter(student__student_user_id=user.id).first()。您正在做的是将学生ID与用户ID进行比较,这不是您想要的。上面修改后的代码将(请求)用户 ID 与学生的用户 ID 进行比较。
  • 是的,你是对的,我没有注意到!再次感谢您
猜你喜欢
  • 2016-12-02
  • 2011-09-12
  • 2018-09-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-19
  • 2011-11-12
  • 1970-01-01
  • 2017-04-29
相关资源
最近更新 更多