- Redis / Celery / Celery Beat
- кэширование популярных тегов и лучших участников
- асинхронные уведомления в Centrifugo
- отправка email-уведомлений через Celery
- полнотекстовый поиск и подсказки
- Docker Compose инфраструктура
This commit is contained in:
redtea committed 2026-05-28 09:48:16 +03:00
1 parent becfbeb070
commit 4bc5fcef7a
154 files changed
+33164 -198

No files matched your search

+56
View File
@@ -6,6 +6,7 @@ from django.utils.http import url_has_allowed_host_and_scheme
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.views.decorators.http import require_POST
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector
from .models import (
Question,
@@ -22,6 +23,7 @@ from .forms import (
AskForm,
AnswerForm
)
from . import tasks as tasks_module
def index(request):
@@ -104,6 +106,30 @@ def hot(request):
})
def search(request):
query_text = request.GET.get('q', '').strip()
if not query_text:
return JsonResponse({'results': []})
vector = SearchVector('title', 'body')
query = SearchQuery(query_text)
questions = Question.objects.annotate(
rank=SearchRank(vector, query)
).filter(rank__gte=0.1).order_by('-rank')[:10]
results = [
{
'id': q.id,
'title': q.title,
'url': f'/question?question_id={q.id}'
}
for q in questions
]
return JsonResponse({'results': results})
def question(request):
question_id = request.GET.get('question_id')
@@ -130,6 +156,36 @@ def question(request):
question=question
)
# trigger async notifications and cache updates
try:
payload = {
'id': answer.id,
'body': answer.body,
'user': answer.user.username
}
tasks_module.publish_new_answer_centrifugo.delay(question.id, payload)
except Exception:
pass
try:
# send email to question author
recipient = []
if hasattr(question.user, 'profile'):
recipient = [question.user.profile.email]
subject = f'New answer to your question: {question.title}'
message = f'User {answer.user.username} answered your question.\n\n{answer.body}'
if recipient and recipient[0]:
tasks_module.send_new_answer_email.delay(subject, message, recipient)
except Exception:
pass
# optionally trigger cache rebuilds
try:
tasks_module.rebuild_popular_tags.delay()
tasks_module.rebuild_best_members.delay()
except Exception:
pass
return redirect(
f'/question?question_id={question.id}#answer-{answer.id}'
)