Django注释来自另一个模型的字段值

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 但找不到合适的解决方案。

Wil*_*sem 8

您可以使用Subquery表达式\xc2\xa0 [Django-doc]

\n
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

  • 非常感谢,它有效!我必须阅读有关子查询的更多信息 (2认同)