简体   繁体   中英

Django model order_by based on another model queryset length

I have 2 models:

models.py

class Post(models.Model):
    title = models.CharField(max_length=255)
    desc = models.CharField(max_length=500)
    content = models.TextField()
    uploadedBy = models.ForeignKey(User, on_delete=models.CASCADE)
    
LIKE_CATEGORIES = (
    ("LIKE", "LIKE"),
    ("DISLIKE", "DISLIKE")
)

class PostLike(models.Model):
    _type = models.CharField(max_length=200, choices=LIKE_CATEGORIES, blank=True, null=True)
    
    content = models.ForeignKey(
        Post, on_delete=models.CASCADE)
        
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    
    created = models.DateTimeField(auto_now_add=True)

I want to order Post based on number of likes a post has. Number of likes a post has is the count of PostLike objects having _type="LIKE",content=post_object .

How can I order Post specifically based on number of likes?

You can annotate each Post with aCount of related PostLike objects, this can have a filter to only count the related objects that satisfy a condition. Then order by the annotation

from django.db.models import Count, Q
Post.objects.annotate(
    likes=Count('postlike', filter=Q(postlike___type="LIKE"))
).order_by('-likes')

I'm not sure having a field with an underscore prefix is the best idea, it may mess up the ORM and other parts of the Django internals

This will restrict your filter to Post with LIKE and also rank it

from django.db.models import Count
Post.objects.filter(postlike___type='LIKE').annotate(likes=Count('postlike')).order_by('-likes')

Or

from django.db.models import Count
Post.objects.filter(postlike___type='LIKE').annotate(Count('postlike'))[::-1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM