django - 跨两个模型的 Django 简单注释
问题描述
我有三个模型,用户、成就和用户成就:
class User(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
...
class Achievement(models.Model):
name = models.CharField(max_length=64)
points = models.PositiveIntegerField(default=1)
class UserAchievement(models.Model):
# Use a lazy reference to avoid circular import issues
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
achievement = models.ForeignKey(Achievement, on_delete=models.CASCADE)
我想用一个“积分”列来注释用户,该列总结了他们在 UserAchievement 表中列出的所有成就所获得的总积分。
但很明显,我并没有完全了解注释的工作方式。当我尝试:
users = User.objects.annotate(points=Sum('userachievement__achievement__points'))
for u in users:
print(u.email, u.points)
它崩溃了:
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/Users/dylan/.local/share/virtualenvs/server-E23dvZwD/lib/python3.7/site-packages/django/db/models/query.py", line 274, in __iter__
self._fetch_all()
File "/Users/dylan/.local/share/virtualenvs/server-E23dvZwD/lib/python3.7/site-packages/django/db/models/query.py", line 1242, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/Users/dylan/.local/share/virtualenvs/server-E23dvZwD/lib/python3.7/site-packages/django/db/models/query.py", line 78, in __iter__
setattr(obj, attr_name, row[col_pos])
AttributeError: can't set attribute
解决方案
您可以使用ManyToManyField from User
to Achievement
using UserAchievement
as a through table 来简化查询
class User(AbstractUser):
email = models.EmailField(_('email address'), unique=True)
achievements = models.ManyToManyField('Achievement', through='UserAchievement')
...
这可以像这样用于注释
User.objects.annotate(points=Sum('achievements__points'))
如果你有一个用户实例
user.achievements.all()
至于错误,我相信您的用户模型上有一个名为 points 的属性
推荐阅读
- java - Java groovy 流比较两个列表并返回单个布尔变量
- unity3d - 获取对序列化列表的引用
在统一 - c# - 在 C# Mono 中使用 Xlib 设置“前景”窗口
- opencv4 - opencv+SaperaLT++ 带有垃圾名称的多个不需要的窗口
- python - 使用棉花糖验证架构时出现 AttributeError
- java - 如何在 Java 数组中建模相互依赖的工作表?
- r - 如何在用户定义函数的 write.csv 参数中放置字符串
- java - Flink 将所有流元素保存在 HashMap 中
- xamarin.forms - MvvmCross.Forms - 自定义 NavigationBar(其中包含 SearchBar)
- c++ - Qtopengl,为什么不能使用不同的vbo绘制两个立方体