Skip to content

Commit

Permalink
feat(article): add article ranking (#370)
Browse files Browse the repository at this point in the history
  • Loading branch information
lin594 committed Oct 13, 2024
1 parent 88735f7 commit e11c9b6
Show file tree
Hide file tree
Showing 7 changed files with 3,597 additions and 5 deletions.
5 changes: 5 additions & 0 deletions hinghwa-dict-backend/HinghwaDict/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,11 @@
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "pronunciation_ranking_cache_table",
},
"article_ranking": {
"TIMEOUT": 900,
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
"LOCATION": "article_ranking_cache_table",
},
}
SIMPLEUI_LOGO = "https://hinghwa.cn/img/blue.7169aa26.svg"
SIMPLEUI_HOME_INFO = False
Expand Down
1 change: 1 addition & 0 deletions hinghwa-dict-backend/article/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@
path("/comments/<int:id>/like", csrf_exempt(LikeComment.as_view())),
path("/comments/<int:id>", csrf_exempt(CommentDetail.as_view())),
path("/comments", csrf_exempt(SearchComment.as_view())),
path("/ranking", csrf_exempt(ArticleRanking.as_view())), # AT0203文章榜单
]
111 changes: 110 additions & 1 deletion hinghwa-dict-backend/article/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import demjson3
import datetime
from django.http import JsonResponse
from django.utils import timezone
from django.views.decorators.csrf import csrf_exempt
Expand All @@ -11,9 +12,12 @@
sendNotification,
)
from .forms import ArticleForm, CommentForm
from django.db.models import Q, Count, Max
from user.dto.user_simple import user_simple
from .models import Article, Comment
from django.conf import settings
from .dto.article_all import article_all
from django.core.cache import caches
from .dto.article_normal import article_normal
from .dto.comment_normal import comment_normal
from .dto.comment_likes import comment_likes
Expand All @@ -22,7 +26,9 @@
from utils.exception.types.bad_request import (
BadRequestException,
ReturnUsersNumException,
RankWithoutDays,
)
from django.core.paginator import Paginator
from utils.exception.types.not_found import (
ArticleNotFoundException,
CommentNotFoundException,
Expand Down Expand Up @@ -78,7 +84,7 @@ def post(self, request) -> JsonResponse:
article.update_time = timezone.now()
article.author = user
article.save()
content = f"我创建了文章(id={article.id}),请及时去审核"
content = f"我创建了文章(id={article.id}),请及时审核"
sendNotification(
article.author,
None,
Expand Down Expand Up @@ -372,3 +378,106 @@ def return_users_num_pass(self, request):
raise ReturnUsersNumException()
return int(request.GET["return_users_num"])
return None


class ArticleRanking(View):
# AT0203 文章上传榜单
def get(self, request) -> JsonResponse:
days = request.GET["days"] # 要多少天的榜单
page = request.GET.get("page", 1) # 获取页面数,默认为第1页
pagesize = request.GET.get("pageSize", 10) # 获取每页显示数量,默认为10条
if not days:
raise RankWithoutDays()
days = int(days)
try:
token = token_pass(request.headers)
user: User = token_user(token)
my_id = user.id
except:
my_id = 0
my_amount = 0
my_rank = 0
rank_count = 0
result_json_list = []
paginator = Pages(self.get_rank_queries(days), pagesize)
current_page = paginator.get_page(page)
adjacent_pages = list(
paginator.get_adjacent_pages(current_page, adjancent_pages=3)
)

for rank_q in self.get_rank_queries(days):
con_id = rank_q["author_id"]
amount = rank_q["article_count"]
rank_count = rank_count + 1
if con_id == my_id:
my_amount = amount
my_rank = rank_count
result_json_list.append(
{
"author": user_simple(User.objects.filter(id=con_id)[0]),
"amount": amount,
}
)
# 发送给前端
return JsonResponse(
{
"ranking": result_json_list,
"me": {"amount": my_amount, "rank": my_rank},
"pagination": {
"total_pages": paginator.num_pages,
"current_page": current_page.number,
"page_size": pagesize,
"previous_page": current_page.has_previous(),
"next_page": current_page.has_next(),
"adjacent_pages": adjacent_pages,
},
},
status=200,
)

@classmethod
def get_rank_queries(cls, days):
rank_cache = caches["article_ranking"]
rank_queries = rank_cache.get(str(days))
if rank_queries is None:
# 发现缓存中没有要查询的天数的榜单,更新榜单,并把更新的表格录入到数据库缓存中article_ranking表的对应位置
rank_queries = cls.update_rank(days)
rank_cache.set(str(days), rank_queries)
return rank_queries

@classmethod
def update_rank(cls, search_days): # 不包括存储在数据库中
if search_days != 0:
start_date = timezone.now() - datetime.timedelta(days=search_days)
# 查询发布时间在规定开始时间之后的
result = (
Article.objects.filter(
Q(publish_time__gt=start_date) & Q(visibility=True)
)
.values("author_id")
.annotate(
article_count=Count("author_id"),
last_date=Max("publish_time"),
)
.order_by("-article_count", "-last_date")
)
else:
result = (
Article.objects.filter(visibility=True)
.values("author_id")
.annotate(
article_count=Count("author_id"),
last_date=Max("publish_time"),
)
.order_by("-article_count", "-last_date")
)
return result # 返回的是Queries


class Pages(Paginator):
# 对原有的Paginator类进行扩展,获取当前页的相邻页面
def get_adjacent_pages(self, current_page, adjancent_pages=3):
current_page = current_page.number
start_page = max(current_page - adjancent_pages, 1) # 前面的页码数
end_page = min(current_page + adjancent_pages, self.num_pages) # 后面的页码数
return range(start_page, end_page + 1)
4 changes: 2 additions & 2 deletions hinghwa-dict-backend/utils/exception/types/bad_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ def __init__(self, msg="可用测试题不足"):
super().__init__(msg)


class PronunciationRankWithoutDays(BadRequestException):
class RankWithoutDays(BadRequestException):
"""
发音排名请求没有发送天数异常
"""

def __init__(self, msg="发音排名请求没有发送天数"):
def __init__(self, msg="排名请求没有发送天数"):
super().__init__(msg)


Expand Down
4 changes: 2 additions & 2 deletions hinghwa-dict-backend/word/pronunciation/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from user.dto.user_simple import user_simple
from utils.exception.types.bad_request import (
BadRequestException,
PronunciationRankWithoutDays,
RankWithoutDays,
InvalidPronunciation,
)
from utils.exception.types.not_found import (
Expand Down Expand Up @@ -498,7 +498,7 @@ def get(self, request) -> JsonResponse:
page = request.GET.get("page", 1) # 获取页面数,默认为第1页
pagesize = request.GET.get("pageSize", 10) # 获取每页显示数量,默认为10条
if not days:
raise PronunciationRankWithoutDays()
raise RankWithoutDays()
days = int(days)
try:
token = token_pass(request.headers)
Expand Down
Loading

0 comments on commit e11c9b6

Please sign in to comment.