我已经阅读了之前的问题,并尝试阅读文档,但我对此没有真正的运气。
我正在使用 Django-tables2 来显示学生的数据。
表中的一列(当前状态)是使用学生模型中模型管理器的访问器填充的,如下所示:
模型.py
class Student(models.Model):
#a bunch of fields
def get_current_standing(self):
current_standing = AcademicStanding.objects.get(year=self.enrol_term, student=self).standing
return current_standing
表.py
class StudentTable(tables.Table):
current_standing = tables.Column(accessor='get_current_standing')
class Meta:
model = Student
fields = ["last_name", "first_name", "campus_id", "current_standing"]
表格可以正确填充和显示,但排序依据会生成错误。我可以按如下方式调整列:
current_standing = tables.Column(accessor='get_current_standing', order_by='academicstanding.standing')
但是因为关系是 1:N,所以我得到了多个结果,其中(如学生模型中的经理所示),我只想要学生在特定入学年份的学术地位。此方法也不根据排名对条目进行分组。
最后,这种使用模型管理器作为访问器填充表的方法是否正确?为了启用正确的预期功能,我缺少什么?
最佳答案
好吧,这有点有趣。如果您给我一个存储库,速度会更快,但您提供了大量信息,因此我能够毫无问题地创建自己的存储库。 :D 起来了 here ,(在撰写本文时提交e7f70e)。
为了整洁起见,我在QuerySet
中做了所有重要的事情,所以看看students/managers.py
.
在这里,您会看到我在上面的评论中无法理解的注释。我已将其翻译为以下更独立的内容:
Student.objects.annotate(current_standing=models.Subquery(
AcademicStanding.objects \
.filter(student=models.OuterRef('id')) \
.filter(year__year=2018) \
.values('standing'),
)
)
适用于以下型号:
class Student(models.Model):
name = models.CharField(max_length=20, ...)
...
class AcademicStanding(models.Model):
student = models.ForeignKey(
'students.Student',
related_name='academic_standings',
on_delete=models.CASCADE,
)
standing = models.PositiveIntegerField()
year = models.DateField()
...
查询利用 models.Subquery
来执行子查询,使用 OuterRef
来引用当前行的 id
,这意味着每个学生
都会获得与其关联的自己的AcademicStanding
,而不是集合中没有该过滤器的第一个AcademicStanding
。
通过如下定义的表,一切都“正常工作”,因为我们感兴趣的值现在本身就位于查询集上。所有性能也保持不变,因为这实际上是在数据库中完成的计算,而不是在具有多个查询的 Python 中完成的。
class StudentTable(tables.Table):
class Meta:
model = Student
fields = ['name', 'current_standing']
<小时/>
我在整个过程中学到的一件很酷的事情是关于RequestConfig
。这是 django-tables2 中的东西,它接受当前请求,并自动执行给定表所需的操作以匹配 GET 参数等。您可以看到它的实际效果 here 。这对我来说是全新的。
对于您的问题 2 - 我怀疑您会发现使用我上面详细介绍的注释来推理和实现要容易得多,但如果没有,请为此发布另一个问题。
(这样我可以获得更多的答案点)。 :P
关于python - Django-filter 和 Django-tables2 使用外部属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48500712/