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
相关产品推荐
相关产品推荐

