#!/usr/bin/env python # -*- coding: utf-8 -*- # 社交相关的东西 # 问题回答数,浏览量,回答评论数,点赞状态…… from __future__ import unicode_literals, absolute_import, print_function from django.db.models import Count, Q from qa.cache import ViewRecord from qa.models.answer import ( Answer, AnswerVote, AnswerFavor, AnswerReply, QuestionFavor, ) from qa.utils import const_strings # view_record model type class QaSocialService(object): """ 问答社交相关的逻辑 """ def get_answer_num_by_question_ids(self, question_ids): """ 通过问题id获取回答数量 :param question_ids: :return: {question_id: num} """ _nums = Answer.objects.filter( question_id__in=question_ids, is_online=True ).values("question_id").annotate(cnt=Count("question_id")).values("question_id", "cnt") result = {} for item in _nums: result[item["question_id"]] = item["cnt"] return result def get_answer_is_voted_by_answer_ids(self, answer_ids, viewer_user_id=None): """ 获取用户点赞状态 :param answer_ids: :param viewer_user_id: :return: """ result = {} if not all([answer_ids, viewer_user_id]): return result avs = list(AnswerVote.objects.filter( answer_id__in=answer_ids, user=viewer_user_id, is_fake=False, ).values_list("answer_id", flat=True)) if avs: result = {av: True for av in avs} return result def get_answer_is_favored_by_answer_ids(self, answer_ids, viewer_user_id=None): """ 获取回答关注状态 :param answer_ids: :param viewer_user_id: :return: """ result = {} if not all([answer_ids, viewer_user_id]): return result avs = list(AnswerFavor.objects.filter( answer_id__in=answer_ids, user_id=viewer_user_id, is_online=True, ).values_list("answer_id", flat=True)) if avs: result = {av: True for av in avs} return result def get_question_is_favored_by_question_ids(self, question_ids, viewer_user_id=None): """ 获取问题关注状态 :param question_ids: :param viewer_user_id: :return: """ result = {} if not all([question_ids, viewer_user_id]): return result avs = list(QuestionFavor.objects.filter( question_id__in=question_ids, user_id=viewer_user_id, is_online=True, ).values_list("question_id", flat=True)) if avs: result = {av: True for av in avs} return result def get_answer_reply_nums_by_answer_ids(self, answer_ids): """ 通过回答id获取评论数 :param answer_ids: :return: """ result = {} if not answer_ids: return result def _get_nums_func(query): _nums = AnswerReply.objects.filter( query ).values("answer_id").annotate(cnt=Count("answer_id")).values("answer_id", "cnt") return {num["answer_id"]: num["cnt"] for num in _nums} base_query = Q(is_online=True, answer_id__in=answer_ids) # 总评论数 answer_comment_nums = _get_nums_func(base_query) # 一级评论数 _query = base_query & Q(commented_reply_id__isnull=True) answer_first_reply_nums = _get_nums_func(_query) for answer_id in answer_ids: result[answer_id] = { "comment_num": answer_comment_nums.get(answer_id, 0), "first_reply_num": answer_first_reply_nums.get(answer_id, 0), } return result def get_amounts_from_redis(self, qa_ids, const_string): """ 批量从缓存中获取数量 :param qa_ids: 问答id :param const_string: 存储类型 const_strings.ANSWER_VIEW :return: """ result = {} qa_ids = list(set(filter(None, qa_ids))) if not all([qa_ids, const_string]): return result view_record = ViewRecord(const_string) _nums = view_record.view_hmget(qa_ids) for _id, _num in zip(qa_ids, _nums): result[_id] = _num and int(_num) or 0 return result