You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django 2.0的员工自助应用:代理模型如何访问User用户名?

解决Django代理模型访问User实例属性的问题

你的代码里存在两个关键问题,导致无法正确访问username属性:

  1. 类定义阶段不能访问实例属性:你在IDM类的类体里直接写了循环去获取groups,这时候super.username是完全错误的——类定义的时候还没有创建任何User/IDM实例,super在这里指向的是User类,而不是某个实例,自然没有username属性。
  2. 类属性会被所有实例共享:你把groups定义成类属性,这意味着所有IDM实例都会共用同一个groups列表,这显然不是你想要的效果。

正确的实现方式

代理模型的核心是它的实例本质上就是原User模型的实例,所以你可以直接在实例方法/属性里用self.username来访问用户的username属性。我们可以把获取groups的逻辑改成实例属性(用@property装饰器),这样每次访问实例的groups时才会去IDM拉取最新数据:

from django.contrib.auth.models import User
import idm
from django.conf import settings

class IDM(User):
    class Meta:
        proxy = True
        ordering = ('username', )

    @property
    def groups(self):
        # 每次访问groups时初始化IDM客户端
        idmclient = idm(settings.IDM_USER, settings.IDM_USER_PASS)
        groups_list = []
        # 直接用self.username访问当前实例的用户名
        idm_user = idmclient.getUser(samaccountname=self.username)
        for group in idm_user.get_groups():
            groups_list.append(group.__dict__)
        return groups_list

为什么这样可行?

  • 代理模型IDM继承自User,所以每个IDM实例都拥有User模型的所有字段和方法,包括username,直接用self.username就能访问。
  • 把groups改成@property后,它成为了实例的动态属性,每个实例的groups都是独立获取的,不会互相干扰,而且每次访问都会获取最新的群组数据。

额外提示

如果你的IDM客户端初始化比较耗时,也可以把它改成懒加载或者缓存,避免每次访问groups都重新初始化客户端。另外要记住:代理模型不能添加新的数据库字段,只能扩展方法和改变模型的行为,这一点你的代码是符合要求的。

内容的提问来源于stack exchange,提问作者Phill93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:27:55