Django Prefetch_Related with Limit

Limit prefetch_related to 1 by a certain criteria

You can annotate your cases with their last status, and then filter on that status to be what you want.

from django.db.models import OuterRef

status_qs = CaseStatus.objects.filter(case=OuterRef('pk')).order_by('-created').values('status__name')[:1]
Case.objects.annotate(last_status=status_qs).filter(last_status=status_name)

Prefetch object and slice

I've gone through comments of what you've linked. It seems that people in the project are aware of the issue. Look here. This comment suggests finding a workaround to limit the query.

django - prefetch only the newest record?

The reason is that Prefetch expects a Django Queryset as the queryset parameter and you are giving an instance of an object.

Change your query as follows:

link_data = LinkTargets.objects.filter(dashboard=True) \
.prefetch_related(
Prefetch(
'linkdata_set',
queryset=LinkData.objects.filter(pk=LinkData.objects.latest('id').pk)
)
)

This does have the unfortunate effect of undoing the purpose of Prefetch to a large degree.

Update
This prefetches exactly one record globally; not the latest LinkData record per LinkTarget.

To prefetch the max LinkData for each LinkTarget you should start at LinkData: you can achieve this as follows:

LinkData.objects.filter(link_target__dashboard=True).values('link_target').annotate(max_id=Max('id'))

This will return a dictionary of {link_target: 12, max_id: 3223}

You can then use this to return the right set of objects; perhaps filter LinkData based on the values of max_id.

That will look something like this:

latest_link_data_pks = LinkData.objects.filter(link_target__dashboard=True).values('link_target').annotate(max_id=Max('id')).values_list('max_id', flat=True)
link_data = LinkTargets.objects.filter(dashboard=True) \
.prefetch_related(
Prefetch(
'linkdata_set',
queryset=LinkData.objects.filter(pk__in=latest_link_data_pks)
)
)

Django prefetch_related fields with nested select_related fields

To improve your prefetch, you can do select_related within TeamMember like this:

from django.db.models import Prefetch

Team.objects.prefetch_related(
Prefetch(
"team_members",
queryset=TeamMembers.objects.select_related("employee__user")
)
)


Related Topics



Leave a reply



Submit