- Redis / Celery / Celery Beat - кэширование популярных тегов и лучших участников - асинхронные уведомления в Centrifugo - отправка email-уведомлений через Celery - полнотекстовый поиск и подсказки - Docker Compose инфраструктура
56 lines
1.8 KiB
Python
56 lines
1.8 KiB
Python
from datetime import timedelta
|
|
from django.utils import timezone
|
|
from django.core.cache import cache
|
|
from django.contrib.auth.models import User
|
|
from django.db.models import Count, Q
|
|
|
|
from .models import Tag
|
|
|
|
|
|
def sidebar_data(request):
|
|
popular_tags = cache.get('popular_tags')
|
|
best_members = cache.get('best_members')
|
|
|
|
if popular_tags is None:
|
|
three_months_ago = timezone.now() - timedelta(days=90)
|
|
popular_qs = Tag.objects.annotate(
|
|
q_count=Count('question', filter=Q(question__created_at__gte=three_months_ago))
|
|
).order_by('-q_count')[:10]
|
|
popular_tags = [
|
|
{'name': tag.name, 'count': tag.q_count}
|
|
for tag in popular_qs
|
|
]
|
|
cache.set('popular_tags', popular_tags, timeout=60 * 60)
|
|
|
|
if best_members is None:
|
|
week_ago = timezone.now() - timedelta(days=7)
|
|
users_q = User.objects.annotate(
|
|
q_count=Count('question', filter=Q(question__created_at__gte=week_ago))
|
|
)
|
|
users_a = User.objects.annotate(
|
|
a_count=Count('answer', filter=Q(answer__created_at__gte=week_ago)))
|
|
|
|
scores = {}
|
|
for u in users_q:
|
|
scores[u.id] = scores.get(u.id, 0) + (u.q_count or 0)
|
|
for u in users_a:
|
|
scores[u.id] = scores.get(u.id, 0) + (u.a_count or 0)
|
|
|
|
best_members_list = User.objects.filter(id__in=list(scores.keys()))
|
|
best_members = [
|
|
{
|
|
'id': u.id,
|
|
'username': u.username,
|
|
'score': scores.get(u.id, 0)
|
|
}
|
|
for u in best_members_list
|
|
]
|
|
best_members.sort(key=lambda x: x['score'], reverse=True)
|
|
best_members = best_members[:10]
|
|
cache.set('best_members', best_members, timeout=60 * 60)
|
|
|
|
return {
|
|
'popular_tags': popular_tags,
|
|
'best_members': best_members,
|
|
}
|