utils.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import numpy as np
  2. from django.utils import timezone
  3. from review.models import Review
  4. from django.db.models import Count
  5. from django.db import connection
  6. def last_month_reviews(location_id):
  7. now = timezone.now()
  8. date = now.replace(day=1)
  9. day = (date - timezone.timedelta(days=1)).day + 1
  10. prev_date = date - timezone.timedelta(days=day)
  11. res = Review.objects.filter(create_time__range=(prev_date, date), location_id=location_id).\
  12. values('star_rating').annotate(total=Count('star_rating')).order_by('star_rating')
  13. ratings = [0] * 5
  14. for r in res:
  15. ratings[r.get('star_rating') - 1] = r.get('total')
  16. return ratings
  17. def weekly_reviews_summary(location_id):
  18. now = timezone.now()
  19. date = now - timezone.timedelta(days=7)
  20. reviews = Review.objects.filter(
  21. create_time__gte=date,
  22. location_id=location_id
  23. )
  24. ratings = reviews.values('star_rating')\
  25. .annotate(total=Count('star_rating'))\
  26. .order_by('-star_rating')
  27. return reviews, ratings
  28. def last_data(date, location_id):
  29. res = Review.objects.filter(create_time__gte=date, location_id=location_id).values('star_rating')\
  30. .annotate(total=Count('star_rating')).order_by('star_rating')
  31. ratings = [0] * 5
  32. for r in res:
  33. ratings[r.get('star_rating')-1] = r.get('total')
  34. return ratings
  35. #
  36. # def get_review_count_by_month(location_id):
  37. # now = timezone.now()
  38. # date = now.replace(day=1) - timezone.timedelta(days=1)
  39. # day = date.day - now.day
  40. # first_day_month = now - timezone.timedelta(days=now.day)
  41. # this_month = last_data(first_day_month, location_id)
  42. # sql = f'''
  43. # SELECT review_id, MONTHNAME(create_time) as month, COUNT(review_id) as total_review
  44. # FROM review_review
  45. # WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  46. # GROUP BY MONTH(create_time)
  47. # ORDER BY DATE(create_time)
  48. # '''
  49. # qs = Review.objects.raw(sql)
  50. # label = [q.month for q in qs]
  51. # total_review = [q.total_review for q in qs]
  52. # star_ratings = []
  53. # for i in range(1, 6):
  54. # sql = f'''
  55. # SELECT review_id, MONTHNAME(create_time) as month, COUNT(review_id) as total_ratings
  56. # FROM review_review
  57. # WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time
  58. # and location_id={location_id} and star_rating={i}
  59. # GROUP BY MONTH(create_time)
  60. # ORDER BY DATE(create_time)
  61. # '''
  62. # qs = Review.objects.raw(sql)
  63. # ratings = [0]*len(label)
  64. #
  65. # for q in qs:
  66. # ratings[label.index(q.month)] = q.total_ratings
  67. # star_ratings.append(ratings)
  68. # response = {
  69. # 'label': label,
  70. # 'total_reviews': total_review,
  71. # 'one_star': star_ratings[0],
  72. # 'two_star': star_ratings[1],
  73. # 'three_star': star_ratings[2],
  74. # 'four_star': star_ratings[3],
  75. # 'five_star': star_ratings[4],
  76. # 'this': this_month
  77. # }
  78. # return response
  79. #
  80. #
  81. # def get_review_count_by_week(location_id):
  82. # now = timezone.now()
  83. # day = 6 - now.weekday()
  84. # first_day_week = now - timezone.timedelta(days=(now.weekday()+1))
  85. # this_week = last_data(first_day_week, location_id)
  86. # sql = f'''
  87. # SELECT review_id, WEEK(create_time) as week, COUNT(review_id) as total_review
  88. # FROM review_review
  89. # WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  90. # GROUP BY WEEK(create_time)
  91. # ORDER BY DATE(create_time)
  92. # '''
  93. # qs = Review.objects.raw(sql)
  94. # label = [q.week for q in qs]
  95. # total_review = [q.total_review for q in qs]
  96. # star_ratings = []
  97. # for i in range(1, 6):
  98. # sql = f'''
  99. # SELECT review_id, WEEK(create_time) as week, COUNT(review_id) as total_ratings
  100. # FROM review_review
  101. # WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time
  102. # and location_id={location_id} and star_rating={i}
  103. # GROUP BY WEEK(create_time)
  104. # ORDER BY DATE(create_time)
  105. # '''
  106. # qs = Review.objects.raw(sql)
  107. # ratings = [0]*len(label)
  108. # for q in qs:
  109. # ratings[label.index(q.week)] = q.total_ratings
  110. # star_ratings.append(ratings)
  111. # response = {
  112. # 'label': label,
  113. # 'total_reviews': total_review,
  114. # 'one_star': star_ratings[0],
  115. # 'two_star': star_ratings[1],
  116. # 'three_star': star_ratings[2],
  117. # 'four_star': star_ratings[3],
  118. # 'five_star': star_ratings[4],
  119. # 'this': this_week
  120. # }
  121. # return response
  122. def monthly_review_count(location_id):
  123. sql = f'''
  124. SELECT MONTHNAME(create_time) as month, star_rating, COALESCE(COUNT(*), 0) as total_review
  125. FROM review_review
  126. WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),
  127. INTERVAL -1 YEAR), INTERVAL 15 DAY) <= create_time and location_id={location_id}
  128. GROUP BY MONTH(create_time), star_rating
  129. ORDER BY create_time;
  130. '''
  131. with connection.cursor() as cursor:
  132. cursor.execute(sql)
  133. rows = cursor.fetchall()
  134. # It will transform a cursor like (('September', 5, 26), ('October', 3, 21), ...)
  135. # to a dict like this {'September_5': 26, 'October_3', 21), ...}
  136. # Here key 'September_5' means 5 star ratings in September month and value is the number of star count.
  137. row_dict = {row[0] + '_' + str(row[1]): row[2] for row in rows}
  138. # Get all month names for graph label
  139. labels = []
  140. for row in rows:
  141. if row[0] not in labels:
  142. labels.append(row[0])
  143. row_lists = []
  144. for i in range(1, 6):
  145. row = [row_dict.get(m+'_'+str(i), 0) for m in labels]
  146. row_lists.append(row)
  147. return labels, row_lists
  148. def get_review_count_by_week(location_id):
  149. now = timezone.now()
  150. day = 6 - now.weekday()
  151. first_day_week = now - timezone.timedelta(days=(now.weekday()+1))
  152. this_week = last_data(first_day_week, location_id)
  153. sql = f'''
  154. SELECT WEEK(create_time) as month, star_rating, COALESCE(COUNT(*), 0) as total_review
  155. FROM review_review
  156. WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),
  157. INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  158. GROUP BY WEEK(create_time), star_rating
  159. ORDER BY create_time;
  160. '''
  161. with connection.cursor() as cursor:
  162. cursor.execute(sql)
  163. rows = cursor.fetchall()
  164. # It will transform a cursor like (('September', 5, 26), ('October', 3, 21), ...)
  165. # to a dict like this {'September_5': 26, 'October_3', 21), ...}
  166. # Here key 'September_5' means 5 star ratings in September month and value is the number of star count.
  167. row_dict = {str(row[0]) + '_' + str(row[1]): row[2] for row in rows}
  168. # Get all week names for graph label
  169. labels = []
  170. for row in rows:
  171. if row[0] not in labels:
  172. labels.append(row[0])
  173. star_ratings = []
  174. for i in range(1, 6):
  175. row = [row_dict.get(str(w) + '_' + str(i), 0) for w in labels]
  176. star_ratings.append(row)
  177. total_review = list(np.sum(star_ratings, axis=0))
  178. response = {
  179. 'label': labels,
  180. 'total_reviews': total_review,
  181. 'one_star': star_ratings[0],
  182. 'two_star': star_ratings[1],
  183. 'three_star': star_ratings[2],
  184. 'four_star': star_ratings[3],
  185. 'five_star': star_ratings[4],
  186. 'this': this_week
  187. }
  188. return response
  189. def get_review_count_by_month(location_id):
  190. now = timezone.now()
  191. date = now.replace(day=1) - timezone.timedelta(days=1)
  192. day = date.day - now.day
  193. first_day_month = now - timezone.timedelta(days=now.day)
  194. this_month = last_data(first_day_month, location_id)
  195. sql = f'''
  196. SELECT MONTHNAME(create_time) as month, star_rating, COALESCE(COUNT(*), 0) as total_review
  197. FROM review_review
  198. WHERE DATE_ADD(DATE_ADD(CURRENT_TIMESTAMP(),
  199. INTERVAL -1 YEAR), INTERVAL {day} DAY) <= create_time and location_id={location_id}
  200. GROUP BY MONTHNAME(create_time), star_rating
  201. ORDER BY create_time;
  202. '''
  203. with connection.cursor() as cursor:
  204. cursor.execute(sql)
  205. rows = cursor.fetchall()
  206. # It will transform a cursor like (('September', 5, 26), ('October', 3, 21), ...)
  207. # to a dict like this {'September_5': 26, 'October_3', 21), ...}
  208. # Here key 'September_5' means 5 star ratings in September month and value is the number of star count.
  209. row_dict = {str(row[0]) + '_' + str(row[1]): row[2] for row in rows}
  210. # Get all month names for graph label
  211. labels = []
  212. for row in rows:
  213. if row[0] not in labels:
  214. labels.append(row[0])
  215. star_ratings = []
  216. for i in range(1, 6):
  217. row = [row_dict.get(str(m) + '_' + str(i), 0) for m in labels]
  218. star_ratings.append(row)
  219. total_review = list(np.sum(star_ratings, axis=0))
  220. response = {
  221. 'label': labels,
  222. 'total_reviews': total_review,
  223. 'one_star': star_ratings[0],
  224. 'two_star': star_ratings[1],
  225. 'three_star': star_ratings[2],
  226. 'four_star': star_ratings[3],
  227. 'five_star': star_ratings[4],
  228. 'this': this_month
  229. }
  230. return response