简体   繁体   English

检查哪个模型是 Django 中当前用户的实例

[英]Check which model is the current user an instance of in Django

The Employee model in my Django project has a OneToOneField relationship with the built-in Django User model.我的 Django 项目中的 Employee 模型与内置的 Django User 模型具有 OneToOneField 关系。 I have then further inherited this Employee model into two different Manager and Associate models.然后我进一步将这个 Employee 模型继承到两个不同的 Manager 和 Associate 模型中。 Now, when a user logs in, I want to check if this user is a Manager or an Associate in my HTML template so that I can display different options, depending on whether they are a Manager or an Associate.现在,当用户登录时,我想检查该用户是我的 HTML 模板中的经理还是助理,以便我可以显示不同的选项,具体取决于他们是经理还是助理。 What is the best way to that?最好的方法是什么?

Models.py-模型.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__()

Ooo, using model inheritance eh?哦,使用模型继承是吧? Django has three types of model inheritance , and based on your problem, it seems like what you need is Meta inheritance . Django 有三种类型的模型继承,根据你的问题,看起来你需要的是Meta 继承

In this case, you want to make your Employee abstract and in the user_def field, define the related_name that provides a backwards relationship from the user to the subclassed models, which in your case would be the Manager or Associate models.在这种情况下,你想使你的Employee抽象,并在user_def领域,定义related_name提供从用户到子类的车型,而你的情况将是一个倒退关系ManagerAssociate车型。 You can't use any related_name however . 但是,您不能使用任何related_name You need to include the app label and class within the related name, eg: related_name="%(app_label)s_%(class)s" .您需要在相关名称中包含应用程序标签和类,例如: related_name="%(app_label)s_%(class)s" Here, the app_label and class would be app labels and classes of Manager and Associate so if you have your models defined in an app called hr , then to get the backwards relation from user ( user is the user instance) to manager, you use user.hr_manager .在这里, app_labelclass将是ManagerAssociate应用程序标签和类,因此如果您在名为hr的应用程序中定义了您的模型,那么要获取从useruser是用户实例)到经理的向后关系,您可以使用user.hr_manager Likewise if the user is associate, use user.hr_associate .同样,如果用户是关联的,请使用user.hr_associate

So, this backwards relation then essentially answers your question because since user has 1-to-1 relation to your Employee model, the user can only either be a manager or an associate.因此,这种向后关系本质上回答了您的问题,因为由于用户与您的Employee模型具有一对一的关系,因此用户只能是经理或员工。 They are mutually exclusive.它们是相互排斥的。 Therefore, if your user is a manager, then that user will return a Manager instance if you ask for user.hr_manager and None if you ask for user.hr_associate .因此,如果您的用户是经理,那么如果您要求user.hr_manager和 None 如果您要求user.hr_associate ,那么该用户将返回一个Manager实例。

Now I notice you have allowed null=True on your OneToOneField, so it is possible that the user will return None for both instances of user.hr_manager and user.hr_associate .现在我注意到您在 OneToOneField 上允许null=True ,因此用户可能会为user.hr_manageruser.hr_associate两个实例返回 None 。 Therefore, just remember to do a thorough if/elif/else check on the user.因此,请记住对用户进行彻底的 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

EDIT: I haven't tested the code, specifically the part about user.hr_manager / user.hr_associate .编辑:我还没有测试代码,特别是关于user.hr_manager / user.hr_associate的部分。 They may actually throw an error instead of None if there is no backwards relationship.如果没有向后关系,它们实际上可能会抛出错误而不是 None 。 In this case, you can simply catch and ignore the errors and move on to the next if/elif/else check.在这种情况下,您可以简单地捕获并忽略错误并继续进行下一个 if/elif/else 检查。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM