Django Query That Get Most Recent Objects From Different Categories
As far as I know, there is no one-step way of doing this in Django ORM, but you can split it into two queries:
from django.db.models import Max
bakeries = Bakery.objects.annotate(
hottest_cake_baked_at=Max('cake__baked_at')
)
hottest_cakes = Cake.objects.filter(
baked_at__in=[b.hottest_cake_baked_at for b in bakeries]
)
If id's of cakes are progressing along with bake_at timestamps, you can simplify and disambiguate the above code (in case two cakes arrives at the same time you can get both of them):
from django.db.models import Max
hottest_cake_ids = Bakery.objects.annotate(
hottest_cake_id=Max('cake__id')
).values_list('hottest_cake_id', flat=True)
hottest_cakes = Cake.objects.filter(id__in=hottest_cake_ids)
BTW credits for this goes to Daniel Roseman, who once answered similar question of mine:
http://groups.google.pl/group/django-users/browse_thread/thread/3b3cd4cbad478d34/3e4c87f336696054?hl=pl&q=
If the above method is too slow, then I know also second method - you can write custom SQL producing only those Cakes, that are hottest in relevant Bakeries, define it as database VIEW, and then write unmanaged Django model for it. It's also mentioned in the above django-users thread. Direct link to the original concept is here:
http://web.archive.org/web/20130203180037/http://wolfram.kriesing.de/blog/index.php/2007/django-nice-and-critical-article#comment-48425
Hope this helps.
Django: query latest posts from different categories
from django.db.models import Max
categories = Category.objects.annotate(most_recent=Max(post__date)).order_by('-most_recent')[:5]
posts = list()
for category in categories:
posts.append(category.post_set.latest())
That annotates the categories with the date of the most recent post as the value of most_recent
, which you can then order by to get the 5 most recent categories.
Then, just loop through the categories and pull out the latest post for each. Done.
Filtering X most recent entries in each category of queryset
pk_to_rank = queryset.annotate(rank=Window(
expression=DenseRank(),
partition_by=('content_type_id',),
order_by=F('access_time').desc(),
)).values_list('pk', 'rank', named=True)
pks_list = sorted(log.pk for log in pk_to_rank if log.rank <= value)
return queryset.filter(pk__in=pks_list)
Managed to do it only this way by spliting queryset in 2 parts. Option with 3 unions is also possible but what if we have 800 options instead 3 - make 800 unions()??? ges not...
Get the latest record with filter in Django
obj= Model.objects.filter(testfield=12).order_by('-id')[0]
Related Topics
Intersection of Two Lists Including Duplicates
Converting List of Tuples into a Dictionary
Pandas Dataframe Stack Multiple Column Values into Single Column
Python - How to Convert JSON File to Dataframe
Most Pythonic Way to Interleave Two Strings
Efficient Way to Add Spaces Between Characters in a String
How to Find Duplicate Elements in Array Using for Loop in Python
Getting the Indices of Several Elements in a Numpy Array at Once
Accessing a Value in a Tuple That Is in a List
How to Use a Custom Comparison Function in Python 3
Why Use Os.Path.Join Over String Concatenation
Having Trouble Making a List of Lists of a Designated Size
How to Sort a List by Length of String Followed by Alphabetical Order