Reputation: 305
I have a model with a version
field.
class Workflow(models.Model):
...
process_id = models.CharField(null=False, max_length=100) # not unique!
version = models.IntegerField(default=1)
enabled = models.BooleanField(default=True, null=False)
I'm trying to find the latest version for each process_id
within a single query. Basically, I want to do the following:
class WorkflowFilterSet(django_filters.FilterSet):
...
only_latest_versions = django_filters.BooleanFilter(method='get_only_latest_versions')
def get_only_latest_versions(self, queryset, field_name, value):
if value:
workflows = []
for worflow in queryset.distinct('process_id'):
workflow_ = queryset.filter(process_id=worflow.process_id,
enabled=True).latest('version')
workflows.append(workflow_)
return workflows # even if I wanted to do like this I can't because I must return a QuerySet
return queryset
How can I do the above with a single query?
Thank you very much!
EDIT:
I could retrieve the latest versions with the following query:
queryset.filter(enabled=True).values('process_id').annotate(max_version=Max('version'))
However, it returns, obviously, only the process_id
and max_version
. How can I retrieve all fields or the objects themselves with this approach?
Upvotes: 1
Views: 89
Reputation: 4264
You can use the Subquery expressions together with OuterRef.
from django.db.models import OuterRef, Subquery
subquery = Workflow.objects.filter(process_id=OuterRef('process_id'), enabled=True).order_by('-version')
queryset = Workflow.objects.filter(version=Subquery(subquery.values('version')[:1]))
The variable queryset
is a Queryset of Workflow
containing the latest version for each process_id
.
Upvotes: 2