#python #django #django-rest-framework
#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,
)
...
Приблизительная операция, которую я хотел бы выполнить в наборе представлений (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()))
Но я получаю один и тот же этап для всех объектов из первого объекта вместо последнего этапа каждого объекта, поэтому логика работы неверна. Я полагаю, я должен избавиться от History.objects.filter, но не могу найти подходящее решение.
Ответ №1:
Вы можете работать с Subquery
выражением [Django-doc]:
from django.db.models import OuterRef, Subquery
class MyModelViewSet(viewsets.ModelViewSet):
# …
def get_queryset(self):
return super().get_queryset().annotate(
last_stage_name=Subquery(
History.objects.filter(
mymodel_id=OuterRef('pk')
).order_by('-created_at').values('stage__name')[:1]
)
)
Комментарии:
1. большое спасибо, это работает! Мне нужно больше узнать о подзапросе