Skip to main content
 首页 » 编程设计

python之用户排名之Django

2024年09月07日35linjiqin

我如何根据帖子总数对用户进行排名。 示例 First:帖子总数 1-10 第二:帖子总数11-20 第三:帖子总数21-30

模型.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() 

请您参考如下方法:

按帖子数对用户进行排序

我们可以用 Post 的数量注释 User,然后在该注释上使用 order_by:

from django.db.models import Count 
 
User.objects.annotate(nposts=Count('post')).order_by('-nposts') 

这里的破折号 (-) 表示我们按降序排序(因此从多篇文章到少篇文章)。如果您删除破折号,则它以升序顺序排列。

为用户分配一个数字等级

我们还可以为每个用户分配一个数字等级(因此 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。这将首先查看我们是否使用 nrank 属性注释了 User。如果不是这种情况, 我们将手动计算 nrank。最后我们返回对应的文本。

所以我们可以例如查询:

u1 = User.objects.first() 
u1.rank_text  # for example "second" 

Selenium here [so-post]如何猴子修补 Django 模型。