async def questions_solved(request): """ Solved questions """ page_query = pagination.get_page_number(url=request.url) count = await Question.filter(accepted_answer=True).count() paginator = pagination.Pagination(page_query, count) results = ( await Question.filter(accepted_answer=True) .prefetch_related("user", "tags") .limit(paginator.page_size) .offset(paginator.offset()) .order_by('-id') ) answer_count = [] for row in results: r = ( await Answer.all() .prefetch_related("question") .filter(question__id=row.id).count() ) answer_count.append(r) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages() ) return templates.TemplateResponse( "questions/questions.html", { "request": request, "results": zip(results, answer_count), "page_controls": page_controls } )
async def filter_search(request): """ Filter search questions by city and available ads (not rented ads in required time) """ a = Ad i = Image r = Review city = request.query_params["city"] start = request.query_params["start"] end = request.query_params["end"] guests = request.query_params["guests"] page_query = pagination.get_page_number(url=request.url) if start > end: return RedirectResponse(url="/") # available apartment (not rented apartment in required time) results = await a.raw( f"SELECT * FROM ad WHERE ad.id NOT IN " f"(SELECT a.id FROM ad AS a JOIN rent AS r " f"ON a.id = r.ad_rent WHERE " f"('{start}' <= r.end_date::date " f"AND '{end}' >= r.start_date::date)) " f"AND ad.visitor = '{guests}' " f"AND ad.city ILIKE '%{city}%';" ).run() count = len(results) paginator = pagination.Pagination(page_query, count) image_results = [ await i.select().where(i.ad_image == item["id"]).first().run() for item in results ] review_count = [ await r.count().where(r.ad == item["id"]).run() for item in results ] review_grades = [] for item in results: review_grades.extend( await r.raw( f"SELECT ROUND(AVG(review_grade)::numeric,2) AS stars " f"FROM review JOIN ad ON review.ad = {item['id']};" ).run() ) review_stars = [ 0 if k["stars"] is None else k["stars"] for k in review_grades ] page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "ads/ads_list.html", { "request": request, "results": zip(results, image_results, review_count, review_stars), "page_controls": page_controls, "count": count, }, )
async def search(request): """ Search ads """ a = Ad i = Image r = Review count = await a.count().run() page_query = pagination.get_page_number(url=request.url) q = request.query_params["q"] count = await count_search_ads(q).run() paginator = pagination.Pagination(page_query, count) results = ( await get_search_ads(q) .limit(paginator.page_size) .offset(paginator.offset()) .order_by(a.id, ascending=False) .run() ) image_results = [ await i.select().where(i.ad_image == item["id"]).first().run() for item in results ] review_count = [ await r.count().where(r.ad == item["id"]).run() for item in results ] review_grades = [] for item in results: review_grades.extend( await r.raw( f"SELECT ROUND(AVG(review_grade)::numeric,2) AS stars " f"FROM review JOIN ad ON review.ad = {item['id']};" ).run() ) review_stars = [ 0 if k["stars"] is None else k["stars"] for k in review_grades ] page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "ads/ads_list.html", { "request": request, "results": zip(results, image_results, review_count, review_stars), "page_controls": page_controls, "count": count, }, )
async def tags(request): """ All tags """ page_query = pagination.get_page_number(url=request.url) tag = request.path_params["tag"] count = ( await Question.all() .prefetch_related("user", "tags") .filter(tags__name=tag) .count() ) paginator = pagination.Pagination(page_query, count) results = ( await Question.all() .prefetch_related("user", "tags") .filter(tags__name=tag) .limit(paginator.page_size) .offset(paginator.offset()) .order_by("-id") ) answer_count = [] for row in results: r = ( await Answer.all() .prefetch_related("question") .filter(question__id=row.id).count() ) answer_count.append(r) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages() ) return templates.TemplateResponse( "questions/tags.html", { "request": request, "results": zip(results, answer_count), "page_controls": page_controls, "tag": tag } )
async def dashboard(request): auth_user = request.user.display_name page_query = pagination.get_page_number(url=request.url) count = await User.all().count() paginator = pagination.Pagination(page_query, count) results = (await User.all().limit(paginator.page_size ).offset(paginator.offset())) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages()) return templates.TemplateResponse( "accounts/dashboard.html", { "request": request, "results": results, "auth_user": auth_user, "page_controls": page_controls, "count": count }, )
async def profile_ads(request): a = Ad auth_user = request.user.display_name page_query = pagination.get_page_number(url=request.url) count = await a.count().where(a.ad_user.username == auth_user).run() paginator = pagination.Pagination(page_query, count) ads = (await get_ads().where(a.ad_user.username == auth_user ).limit(paginator.page_size ).offset(paginator.offset()).run()) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "accounts/profile_ads.html", { "request": request, "ads": ads, "page_controls": page_controls, }, )
async def profile_questions(request): p = Question auth_user = request.user.display_name page_query = pagination.get_page_number(url=request.url) count = await p.count().where(p.user.username == auth_user).run() paginator = pagination.Pagination(page_query, count) if request.user.is_authenticated: questions = (await get_questions().where(p.user.username == auth_user).limit( paginator.page_size).offset(paginator.offset()).run()) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "accounts/profile_questions.html", { "request": request, "questions": questions, "page_controls": page_controls, }, )
async def profile_notifications(request): n = Notification auth_user = request.user.display_name page_query = pagination.get_page_number(url=request.url) count = await n.count().where(n.recipient.username == auth_user).run() paginator = pagination.Pagination(page_query, count) notifications = (await n.select( n.id, n.message, n.created, n.is_read, n.sender.username).where(n.recipient.username == auth_user ).limit(paginator.page_size ).offset(paginator.offset()).run()) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "accounts/profile_notifications.html", { "request": request, "notifications": notifications, "page_controls": page_controls, }, )
async def search(request): """ Search questions """ try: page_query = pagination.get_page_number(url=request.url) q = request.query_params['q'] count = ( await Question.all() .prefetch_related("user") .filter(Q(title__icontains=q) | Q(content__icontains=q) | Q(user__username__icontains=q)) .distinct() .count() ) paginator = pagination.Pagination(page_query, count) results = ( await Question.all() .prefetch_related("user", "tags") .filter(Q(title__icontains=q) | Q(content__icontains=q) | Q(user__username__icontains=q) | Q(tags__name__icontains=q)) .distinct() .limit(paginator.page_size) .offset(paginator.offset()) ) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages() ) except KeyError: page_query = pagination.get_page_number(url=request.url) count = await Question.all().count() paginator = pagination.Pagination(page_query, count) results = ( await Question.all() .prefetch_related("user", "tags") .limit(paginator.page_size) .offset(paginator.offset()) ) page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages() ) answer_count = [] for row in results: r = ( await Answer.all() .prefetch_related("question") .filter(question__id=row.id).count() ) answer_count.append(r) return templates.TemplateResponse( "questions/search.html", { "request": request, "results": zip(results, answer_count), "page_controls": page_controls, "count": count, "q": q } )
async def questions_categories(request): """ Questions categories """ p = Question category = request.path_params["category"] page_query = pagination.get_page_number(url=request.url) count = await p.count().where(p.category.name == category).run() paginator = pagination.Pagination(page_query, count) try: tab = request.query_params["tab"] if tab == "oldest": results = ( await get_questions() .where(p.category.name == category) .limit(paginator.page_size) .offset(paginator.offset()) .order_by(p.id, ascending=True) .run() ) if tab == "unsolved": count = len( await get_questions().where(p.accepted_answer == False).run() ) paginator = pagination.Pagination(page_query, count) results = ( await get_questions() .where( (p.accepted_answer == False) & (p.category.name == category) ) .limit(paginator.page_size) .offset(paginator.offset()) .order_by(p.id, ascending=False) .run() ) if tab == "solved": count = len( await get_questions().where(p.accepted_answer == True).run() ) paginator = pagination.Pagination(page_query, count) results = ( await get_questions() .where( (p.accepted_answer == True) & (p.category.name == category) ) .limit(paginator.page_size) .offset(paginator.offset()) .order_by(p.id, ascending=False) .run() ) except KeyError: results = ( await get_questions() .where(p.category.name == category) .limit(paginator.page_size) .offset(paginator.offset()) .order_by(p.id, ascending=False) .run() ) answer_count = [ await p.raw( f"select count(answer.id) from answer " f"join question on answer.question = question.id " f"where question.id = {item['id']};" ).run() for item in results ] c = Category categories = await c.select().order_by(c.name, ascending=True).run() category_count = [ await p.count().where(p.category.name == item["name"]).run() for item in categories ] page_controls = pagination.get_page_controls( url=request.url, current_page=paginator.current_page(), total_pages=paginator.total_pages(), ) return templates.TemplateResponse( "questions/questions_categories.html", { "request": request, "results": zip(results, answer_count), "categories": zip(categories, category_count), "page_controls": page_controls, "r": results, }, )