如何根据用户的总帖子对用户进行排名。 示例第一:帖子总数1-10 第二:帖子总数11-20 第三:帖子总数21-30
models.py
from django.db import models
User = get_user_model()
class Post(models.Model):
author = models.ForeignKey(User, on_delete = models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
def get_absolute_url(self):
return reverse("post_detail",kwargs={'pk':self.pk})
def __str__(self):
return self.title
def count_posts_of(user):
return Post.objects.filter(author=user).count()
答案 0 :(得分:2)
User
我们可以使用User
的数量注释Post
,然后在该注释上使用order_by
:
from django.db.models import Count
User.objects.annotate(nposts=Count('post')).order_by('-nposts')
此处短划线(-
)表示我们按降序顺序排序(因此从很多帖子到很少的帖子)。如果您删除短划线,则按升序顺序排序。
User
s 我们还可以为每个用户分配一个数字排名(所以1-10映射到1
,11-20映射到2
等),添加一些额外注释:
from django.db.models import Count, F
from django.db.models.expressions import Func
User.objects.annotate(
nposts=Count('post'),
nrank=Func(F('nposts') / 10, function='CEIL'),
).order_by('-nposts')
我们可以通过定义@property
:
from django.contrib.auth import User
RANK_TEXTS = ['zero', 'first', 'second', 'third']
def rank_text(self):
nrank = getattr(self, 'nrank', None)
if nrank is None:
nrank = (Post.objects(author=self).count() + 9) // 10
return RANK_TEXTS[nrank]
User.rank_text = property(rank_text)
所以我们猴子补丁 User
类,使其具有属性rank_text
。如果我们使用User
属性对nrank
进行注释,则会首先查看。如果不,我们会手动计算nrank
。最后,我们返回文本副本。
因此我们可以查询:
u1 = User.objects.first()
u1.rank_text # for example "second"
Se here [so-post]如何修补Django模型。