bum*_*bee 2 python django django-rest-framework
我想用另一个历史模型中的值来注释 MyModel 查询集。我的模型关系如下:
class Stage(models.Model):
name = models.CharField()
class History(models.Model):
mymodel = models.ForeignKey(
MyModel,
on_delete=models.CASCADE,
)
stage = models.ForeignKey(
Stage,
on_delete=models.DO_NOTHING
)
created_at = models.DateTimeField(
auto_now_add=True
)
class MyModel(models.Model):
id = models.AutoField(
primary_key=True,
)
...
Run Code Online (Sandbox Code Playgroud)
我想在 ViewSet 中执行的大致操作(order_by 我需要获取最新阶段):
class MyModelViewSet(viewsets.ModelViewSet):
...
def get_queryset(self):
qs = super(MyModelViewSet, self).get_queryset()
qs = qs.annotate(last_stage_name=Value(
History.objects.filter(mymodel__id=F('id')).order_by('-created_at')[0].stage.name,
output_field=CharField()))
Run Code Online (Sandbox Code Playgroud)
但是我从第一个对象获得所有对象的相同阶段,而不是每个对象的最新阶段,因此操作逻辑是错误的。我想我应该摆脱 History.objects.filter 但找不到合适的解决方案。
您可以使用Subquery表达式\xc2\xa0 [Django-doc]:
from django.db.models import OuterRef, Subquery\n\nclass MyModelViewSet(viewsets.ModelViewSet):\n \n # …\n \n def get_queryset(self):\n return super().get_queryset().annotate(\n last_stage_name=Subquery(\n History.objects.filter(\n mymodel_id=OuterRef(\'pk\')\n ).order_by(\'-created_at\').values(\'stage__name\')[:1]\n )\n )Run Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
4987 次 |
| 最近记录: |