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

Django调用抽象Device模型字段无法渲染到模板的问题求助

错误原因
  • 第一个报错AttributeError: Manager isn't available; Device is abstract是因为django_otp.models.Device是Django抽象模型,不会映射实际数据库表,本身不提供ORM查询能力,不能直接调用objects执行查询。
  • 第二个报错AttributeError: type object 'DeviceManager' has no attribute 'objects'是因为DeviceManager是模型管理器类,需要绑定到具体的非抽象模型才能使用,不能直接调用管理器类本身的objects属性。
解决方法

1. 导入具体的非抽象设备子类

django-otp的抽象Device模型有多个开箱即用的实现子类,你需要根据实际使用的二次验证类型导入对应子类,常见子类如下:

  • TOTP动态口令设备:from django_otp.plugins.otp_totp.models import TOTPDevice
  • HOTP计数器口令设备:from django_otp.plugins.otp_hotp.models import HOTPDevice
  • 静态备用口令设备:from django_otp.plugins.otp_static.models import StaticDevice

2. 修改视图查询逻辑

可以直接调用子类管理器自带的devices_for_user方法快速获取对应用户的设备,示例代码如下:

# 以TOTP设备为例,如有多种设备类型可自行扩展
from django_otp.plugins.otp_totp.models import TOTPDevice

def account(request):
    user = request.user
    # confirmed参数传True表示仅查询已确认的可用设备,传None查询全部设备
    devices = TOTPDevice.objects.devices_for_user(user, confirmed=True)
    context = {"user": user, "devices": devices}
    return render(request, 'account.html', context)

如果需要同时查询多种类型的设备,可以用itertools.chain合并查询结果:

from itertools import chain
from django_otp.plugins.otp_totp.models import TOTPDevice
from django_otp.plugins.otp_hotp.models import HOTPDevice
from django_otp.plugins.otp_static.models import StaticDevice

def account(request):
    user = request.user
    totp_devices = TOTPDevice.objects.devices_for_user(user, confirmed=True)
    hotp_devices = HOTPDevice.objects.devices_for_user(user, confirmed=True)
    static_devices = StaticDevice.objects.devices_for_user(user, confirmed=True)
    # 合并所有设备列表传入模板
    all_devices = list(chain(totp_devices, hotp_devices, static_devices))
    context = {"user": user, "devices": all_devices}
    return render(request, 'account.html', context)

3. 调整模板渲染逻辑

查询返回的是设备列表,需要遍历渲染,不要直接调用属性:

{% for device in devices %}
<div>
  <p>设备名称:{{ device.name }}</p>
  <p>是否已启用:{{ device.confirmed }}</p>
</div>
{% empty %}
<p>您还没有绑定二次验证设备</p>
{% endfor %}

如果确认用户只会有一个设备,也可以在视图中用devices.first()取单个设备对象,直接在模板调用{{ device.name }}即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:57:00