首页 > 解决方案 > 检查哪个模型是当前用户在 Django 中的实例

问题描述

我的 Django 项目中的 Employee 模型与内置的 Django User 模型具有 OneToOneField 关系。然后,我将这个 Employee 模型进一步继承到两个不同的 Manager 和 Associate 模型中。现在,当用户登录时,我想在我的 HTML 模板中检查该用户是经理还是助理,以便我可以显示不同的选项,具体取决于他们是经理还是助理。最好的方法是什么?

模型.py-

GENDER = [('male','Male'),('female','Female')]

class Employee(models.Model):
    user_def = models.OneToOneField(User,on_delete=models.CASCADE,null=True)
    name = models.CharField(max_length = 50)
    age = models.IntegerField()
    gender = models.CharField(max_length = 10,choices = GENDER)

    def __str__(self):
        return self.name

class Manager(Employee):
    dept = models.CharField(max_length = 50)

    def __str__(self):
        return super().__str__()

class Associate(Employee):
    reports_to = models.ForeignKey(Manager,on_delete=models.CASCADE)

    def __str__(self):
        return super().__str__()

标签: pythondjangodjango-modelsdjango-viewsdjango-templates

解决方案


哦,使用模型继承是吗?Django有三种模型继承,根据你的问题,你需要的是元继承

在这种情况下,您希望进行Employee抽象并在user_def字段中定义related_name提供从用户到子类模型的反向关系的 ,在您的情况下,子类模型将是ManagerorAssociate模型。但是你不能使用任何related_name。您需要在相关名称中包含应用标签和类,例如:related_name="%(app_label)s_%(class)s". 在这里,app_labelandclass将是应用程序的标签和类,Manager因此Associate如果您在名为 的应用程序中定义了模型hr,那么要获得从useruser是用户实例)到管理器的反向关系,您可以使用user.hr_manager. 同样,如果用户是关联用户,请使用user.hr_associate.

因此,这种向后关系基本上回答了您的问题,因为由于用户与您的Employee模型具有一对一的关系,因此用户只能是经理或助理。它们是相互排斥的。因此,如果您的用户是经理,那么如果您要求,该用户将返回一个Manager实例,如果您要求,该用户将返回user.hr_managerNone user.hr_associate

现在我注意到您已null=True在 OneToOneField 上允许,因此用户可能会为user.hr_manager和的两个实例返回 None user.hr_associate。因此,请记住对用户进行彻底的 if/elif/else 检查。

GENDER = [('male','Male'),('female','Female')]

class Employee(models.Model):
    user_def = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        null=True,
        related_name="%(app_label)s_%(class)s"
    )
    name = models.CharField(max_length=50)
    age = models.IntegerField()
    gender = models.CharField(
        max_length=10,
        choices = GENDER
    )

    class Meta:
        abstract = True

class Manager(Employee):
    dept = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Associate(Employee):
    reports_to = models.ForeignKey(
        Manager,
        on_delete=models.CASCADE
    )

    def __str__(self):
        return self.name

编辑:我没有测试过代码,特别是关于user.hr_manager/的部分user.hr_associate。如果没有反向关系,它们实际上可能会抛出错误而不是 None 。在这种情况下,您可以简单地捕获并忽略错误并继续进行下一个 if/elif/else 检查。


推荐阅读