用户排名 - Django

时间:2018-06-12 17:04:29

标签: python django

如何根据用户的总帖子对用户进行排名。 示例第一:帖子总数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()

1 个答案:

答案 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模型。