def searchtable(request): if request.method == 'GET': return HttpResponse('登录成功了,返回吧。这个页面还没做') # time.sleep(0.1) # 测试前端用户感知,测试结束去掉 json_data = request.body.decode('utf-8') info = json.loads(json_data) find_str = info.get('find_str', '') current_page = info.get('pn', 1) # table_names = TableData.objects.filter(table_name__contains=find_str).values('table_name')[:10] table_names = TableData.objects.filter( table_name__contains=find_str).values('table_name').order_by() paginator = Paginator(table_names, 10) # Paginator生成一个对象,然后传入queryset, try: # 以及每页显示的个数,这里每页显示十个 page_obj = paginator.page(current_page) # 根据get方法取到的数字显示页数 except EmptyPage as e: # 如果get方法获取了一个没有的页数则显示第一页 page_obj = paginator.page(1) except PageNotAnInteger as e: # 传入一个字符串也显示第一页 page_obj = paginator.page(1) pagerange = paginator.get_elided_page_range(current_page, on_each_side=3, on_ends=2) page_obj.my_page_range = pagerange return render(request, 'mycharts/searchresult.html', { 'tables': table_names, 'page_obj': page_obj })
def get(self, request): """lets see your cute faces""" filters = {} software = request.GET.get("software") if not software or software == "bookwyrm": filters["bookwyrm_user"] = True scope = request.GET.get("scope") if scope == "local": filters["local"] = True users = suggested_users.get_annotated_users(request.user, **filters) sort = request.GET.get("sort") if sort == "recent": users = users.order_by("-last_active_date") else: users = users.order_by("-mutuals", "-last_active_date") paginated = Paginator(users, 12) page = paginated.get_page(request.GET.get("page")) data = { "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "users": page, } return TemplateResponse(request, "directory/directory.html", data)
def get(self, request): """view current reports""" filters = {} resolved = request.GET.get("resolved") == "true" server = request.GET.get("server") if server: filters["user__federated_server__server_name"] = server username = request.GET.get("username") if username: filters["user__username__icontains"] = username filters["resolved"] = resolved reports = models.Report.objects.filter(**filters) paginated = Paginator(reports, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "resolved": resolved, "server": server, "reports": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), } return TemplateResponse(request, "settings/reports/reports.html", data)
def listing(request, page): keywords = Keyword.objects.all().order_by("name") paginator = Paginator(keywords, 2) page_object = paginator.get_page(page) page_object.adjusted_elided_pages = paginator.get_elided_page_range(page) context = {"page_obj": page_object} return render(request, "terms/keyword_list.html", context)
def get(self, request, job_id): """status of an import job""" job = get_object_or_404(models.ImportJob, id=job_id) if job.user != request.user: raise PermissionDenied() items = job.items.order_by("index").filter(fail_reason__isnull=False, book_guess__isnull=True) paginated = Paginator(items, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "job": job, "items": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "complete": True, } return TemplateResponse(request, "import/troubleshoot.html", data)
def get(self, request, author_id): """landing page for an author""" author = get_object_or_404(models.Author, id=author_id) if is_api_request(request): return ActivitypubResponse(author.to_activity()) default_editions = models.Edition.objects.filter( parent_work=OuterRef("parent_work") ).order_by("-edition_rank") books = ( models.Edition.viewer_aware_objects(request.user) .filter(Q(authors=author) | Q(parent_work__authors=author)) .annotate(default_id=Subquery(default_editions.values("id")[:1])) .filter(default_id=F("id")) .order_by("-first_published_date", "-published_date", "-created_date") .prefetch_related("authors") ).distinct() paginated = Paginator(books, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "author": author, "books": page, "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), } return TemplateResponse(request, "author/author.html", data)
def pendingDiagnosis(request): if request.method == 'POST': request.session['appointment_id'] = request.POST.get('appointment') return redirect('/doctor/pendingDiagnosis/call') # return redirect('/doctor/pendingDiagnosis/detail') identity_card_no = request.session['identity_card_no'] doctor = models.Doctor.objects.get(identity_card_no=identity_card_no) appointment_records = models.Appointment.objects.filter(doctor=doctor, isActive=True) appointment_records = appointment_records.order_by('-appointment_date', '-appointment_time', '-create_time') # 排序 num_per_page = 5 paginator = Paginator(appointment_records, num_per_page) page = request.GET.get('page', 1) try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) is_paginated = True if paginator.num_pages > 1 else False page_range = paginator.get_elided_page_range(page, on_each_side=3, on_ends=2) return render(request, 'doctor/pending.html', locals())
def get(self, request, book_id): """list of editions of a book""" work = get_object_or_404(models.Work, id=book_id) if is_api_request(request): return ActivitypubResponse(work.to_edition_list(**request.GET)) filters = {} if request.GET.get("language"): filters["languages__contains"] = [request.GET.get("language")] if request.GET.get("format"): filters["physical_format__iexact"] = request.GET.get("format") editions = work.editions.order_by("-edition_rank") languages = set(sum(editions.values_list("languages", flat=True), [])) editions = editions.filter(**filters) query = request.GET.get("q") if query: searchable_array_fields = ["languages", "publishers"] searchable_fields = [ "title", "physical_format", "isbn_10", "isbn_13", "oclc_number", "asin", ] search_filter_entries = [{ f"{f}__icontains": query } for f in searchable_fields] + [{ f"{f}__iexact": query } for f in searchable_array_fields] editions = editions.filter( reduce(operator.or_, (Q(**f) for f in search_filter_entries))) paginated = Paginator(editions, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "editions": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "work": work, "work_form": forms.EditionFromWorkForm(instance=work), "languages": languages, "formats": set(e.physical_format.lower() for e in editions if e.physical_format), } return TemplateResponse(request, "book/editions/editions.html", data)
def get(self, request): """view a list of requests""" ignored = request.GET.get("ignored", False) sort = request.GET.get("sort") sort_fields = [ "created_date", "invite__times_used", "invite__invitees__created_date", ] # pylint: disable=consider-using-f-string if not sort in sort_fields + ["-{:s}".format(f) for f in sort_fields]: sort = "-created_date" requests = models.InviteRequest.objects.filter( ignored=ignored).order_by(sort) status_filters = [ s for s in request.GET.getlist("status") if s in ["requested", "sent", "accepted"] ] filters = [] if "requested" in status_filters: filters.append({"invite__isnull": True}) if "sent" in status_filters: filters.append({"invite__isnull": False, "invite__times_used": 0}) if "accepted" in status_filters: filters.append({ "invite__isnull": False, "invite__times_used__gte": 1 }) if filters: requests = requests.filter( reduce(operator.or_, (Q(**f) for f in filters))).distinct() paginated = Paginator(requests, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "ignored": ignored, "count": paginated.count, "requests": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "sort": sort, } return TemplateResponse( request, "settings/invites/manage_invite_requests.html", data)
def get_proper_elided_page_range(paginator, number, on_each_side=3, on_ends=2): """ Paginator.get_elided_page_range() takes some arguments that can't be passed in when using it in a template, so do it with a template tag https://docs.djangoproject.com/en/3.2/ref/paginator/#django.core.paginator.Paginator.get_elided_page_range """ p = Paginator(paginator.object_list, paginator.per_page) return p.get_elided_page_range(number=number, on_each_side=on_each_side, on_ends=on_ends)
def get(self, request, list_id, list_key): """display a book list""" book_list = get_object_or_404(models.List, id=list_id) embed_key = str(book_list.embed_key.hex) if list_key != embed_key: raise Http404() # sort_by shall be "order" unless a valid alternative is given sort_by = request.GET.get("sort_by", "order") if sort_by not in ("order", "title", "rating"): sort_by = "order" # direction shall be "ascending" unless a valid alternative is given direction = request.GET.get("direction", "ascending") if direction not in ("ascending", "descending"): direction = "ascending" directional_sort_by = { "order": "order", "title": "book__title", "rating": "average_rating", }[sort_by] if direction == "descending": directional_sort_by = "-" + directional_sort_by items = book_list.listitem_set.prefetch_related( "user", "book", "book__authors") if sort_by == "rating": items = items.annotate(average_rating=Avg( Coalesce("book__review__rating", 0.0), output_field=DecimalField(), )) items = items.filter(approved=True).order_by(directional_sort_by) paginated = Paginator(items, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "list": book_list, "items": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), } return TemplateResponse(request, "lists/embed-list.html", data)
def makeAppointment(request): patient = models.Patient.objects.get( identity_card_no=request.session['identity_card_no']) if request.method == 'POST': # 统计已有挂号数,假如超过两个不允许再挂号 patient = models.Patient.objects.get( identity_card_no=request.session['identity_card_no']) num = len( models.Appointment.objects.filter(patient=patient, isActive=True)) # 待修改 if num > 100: message = '挂号多于两个' return render(request, 'patient/makeAppointment.html', locals()) appointment = models.Appointment() appointment.patient = models.Patient.objects.get( identity_card_no=request.session['identity_card_no']) appointment.doctor = models.Doctor.objects.get( identity_card_no=request.POST.get('appointment_doctor_id')) appointment.appointment_time = request.POST.get('appointment_time') appointment.appointment_date = request.POST.get('appointment_date') appointment.isActive = True appointment.save() request.session['appointment_id'] = appointment.id return redirect('/patient/makeAppointment/detail') departs = [depart[0] for depart in models.Doctor.department_choices] departs_ = [depart[1] for depart in models.Doctor.department_choices] depart = request.GET.get( 'depart', departs_[0] if 'depart' not in request.session else request.session['depart']) request.session['depart'] = depart # print('科室', depart, departs_.index(depart)) records = models.Doctor.objects.filter( department=departs[departs_.index(depart)]) num_per_page = 5 paginator = Paginator(records, num_per_page) page = request.GET.get('page', 1) try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) is_paginated = True if paginator.num_pages > 1 else False page_range = paginator.get_elided_page_range(page, on_each_side=3, on_ends=2) return render(request, 'patient/makeAppointment.html', locals())
def get(self, request, job_id): """status of an import job""" job = get_object_or_404(models.ImportJob, id=job_id) if job.user != request.user: raise PermissionDenied() items = job.items.order_by("index") item_count = items.count() or 1 paginated = Paginator(items, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) manual_review_count = items.filter(fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True).count() fail_count = items.filter(fail_reason__isnull=False, book_guess__isnull=True).count() pending_item_count = job.pending_items.count() data = { "job": job, "items": page, "manual_review_count": manual_review_count, "fail_count": fail_count, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "item_count": item_count, "complete_count": item_count - pending_item_count, "percent": math.floor( # pylint: disable=c-extension-no-member (item_count - pending_item_count) / item_count * 100), # hours since last import item update "inactive_time": (job.updated_date - timezone.now()).seconds / 60 / 60, "legacy": not job.mappings, } return TemplateResponse(request, "import/import_status.html", data)
def appointment(request): identity_card_no = request.session['identity_card_no'] patient = models.Patient.objects.get(identity_card_no=identity_card_no) appointments = models.Appointment.objects.filter(patient=patient) num_per_page = 5 paginator = Paginator(appointments, num_per_page) page = request.GET.get('page', 1) try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) is_paginated = True if paginator.num_pages > 1 else False page_range = paginator.get_elided_page_range(page, on_each_side=3, on_ends=2) return render(request, 'patient/appointment.html', locals())
def get(self, request): """invite management page""" paginated = Paginator( models.SiteInvite.objects.filter(user=request.user).order_by( "-created_date" ), PAGE_LENGTH, ) page = paginated.get_page(request.GET.get("page")) data = { "invites": page, "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), "form": forms.CreateInviteForm(), } return TemplateResponse(request, "settings/invites/manage_invites.html", data)
def get_context_data(self, **kwargs: dict) -> dict: context = super().get_context_data(**kwargs) page = self.request.GET.get("page", 1) team = context["team"] team_service = TeamService() context["parent_teams"] = team_service.get_all_parent_teams(team) context["sub_teams"] = team_service.get_all_child_teams(team) members = self.get_team_members(team, context["sub_teams"]) paginator = Paginator(members, 40) context["team_members"] = paginator.page(page) context["page_numbers"] = list(paginator.get_elided_page_range(page)) context["heading"] = self.heading return context
def diagnosis(request): if request.method == 'POST': request.session['diagnosis'] = request.POST.get('diagnosis') return redirect('/patient/diagnosis/detail') identity_card_no = request.session['identity_card_no'] patient = models.Patient.objects.get(identity_card_no=identity_card_no) diagnosis_records = models.Diagnosis.objects.filter(patient=patient) num_per_page = 5 paginator = Paginator(diagnosis_records, num_per_page) page = request.GET.get('page', 1) try: page_obj = paginator.page(page) except PageNotAnInteger: page_obj = paginator.page(1) except EmptyPage: page_obj = paginator.page(paginator.num_pages) is_paginated = True if paginator.num_pages > 1 else False page_range = paginator.get_elided_page_range(page, on_each_side=3, on_ends=2) return render(request, 'patient/diagnosis.html', locals())
def get(self, request, status="federated"): """list of servers""" servers = models.FederatedServer.objects.filter(status=status) sort = request.GET.get("sort") sort_fields = ["created_date", "application_type", "server_name"] # pylint: disable=consider-using-f-string if not sort in sort_fields + ["-{:s}".format(f) for f in sort_fields]: sort = "-created_date" servers = servers.order_by(sort) paginated = Paginator(servers, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "servers": page, "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), "sort": sort, "form": forms.ServerForm(), } return TemplateResponse(request, "settings/federation/instance_list.html", data)
def get(self, request, author_id): """landing page for an author""" author = get_object_or_404(models.Author, id=author_id) if is_api_request(request): return ActivitypubResponse(author.to_activity()) books = models.Work.objects.filter( authors=author, editions__authors=author).distinct() paginated = Paginator(books, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) data = { "author": author, "books": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), } return TemplateResponse(request, "author/author.html", data)
def test_get_elided_page_range(self): # Paginator.validate_number() must be called: paginator = Paginator([1, 2, 3], 2) with unittest.mock.patch.object(paginator, "validate_number") as mock: mock.assert_not_called() list(paginator.get_elided_page_range(2)) mock.assert_called_with(2) ELLIPSIS = Paginator.ELLIPSIS # Range is not elided if not enough pages when using default arguments: paginator = Paginator(range(10 * 100), 100) page_range = paginator.get_elided_page_range(1) self.assertIsInstance(page_range, collections.abc.Generator) self.assertNotIn(ELLIPSIS, page_range) paginator = Paginator(range(10 * 100 + 1), 100) self.assertIsInstance(page_range, collections.abc.Generator) page_range = paginator.get_elided_page_range(1) self.assertIn(ELLIPSIS, page_range) # Range should be elided if enough pages when using default arguments: tests = [ # on_each_side=3, on_ends=2 (1, [1, 2, 3, 4, ELLIPSIS, 49, 50]), (6, [1, 2, 3, 4, 5, 6, 7, 8, 9, ELLIPSIS, 49, 50]), (7, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ELLIPSIS, 49, 50]), (8, [1, 2, ELLIPSIS, 5, 6, 7, 8, 9, 10, 11, ELLIPSIS, 49, 50]), (43, [1, 2, ELLIPSIS, 40, 41, 42, 43, 44, 45, 46, ELLIPSIS, 49, 50]), (44, [1, 2, ELLIPSIS, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]), (45, [1, 2, ELLIPSIS, 42, 43, 44, 45, 46, 47, 48, 49, 50]), (50, [1, 2, ELLIPSIS, 47, 48, 49, 50]), ] paginator = Paginator(range(5000), 100) for number, expected in tests: with self.subTest(number=number): page_range = paginator.get_elided_page_range(number) self.assertIsInstance(page_range, collections.abc.Generator) self.assertEqual(list(page_range), expected) # Range is not elided if not enough pages when using custom arguments: tests = [ (6, 2, 1, 1), (8, 1, 3, 1), (8, 4, 0, 1), (4, 1, 1, 1), # When on_each_side and on_ends are both <= 1 but not both == 1 it # is a special case where the range is not elided until an extra # page is added. (2, 0, 1, 2), (2, 1, 0, 2), (1, 0, 0, 2), ] for pages, on_each_side, on_ends, elided_after in tests: for offset in range(elided_after + 1): with self.subTest( pages=pages, offset=elided_after, on_each_side=on_each_side, on_ends=on_ends, ): paginator = Paginator(range((pages + offset) * 100), 100) page_range = paginator.get_elided_page_range( 1, on_each_side=on_each_side, on_ends=on_ends, ) self.assertIsInstance(page_range, collections.abc.Generator) if offset < elided_after: self.assertNotIn(ELLIPSIS, page_range) else: self.assertIn(ELLIPSIS, page_range) # Range should be elided if enough pages when using custom arguments: tests = [ # on_each_side=2, on_ends=1 (1, 2, 1, [1, 2, 3, ELLIPSIS, 50]), (4, 2, 1, [1, 2, 3, 4, 5, 6, ELLIPSIS, 50]), (5, 2, 1, [1, 2, 3, 4, 5, 6, 7, ELLIPSIS, 50]), (6, 2, 1, [1, ELLIPSIS, 4, 5, 6, 7, 8, ELLIPSIS, 50]), (45, 2, 1, [1, ELLIPSIS, 43, 44, 45, 46, 47, ELLIPSIS, 50]), (46, 2, 1, [1, ELLIPSIS, 44, 45, 46, 47, 48, 49, 50]), (47, 2, 1, [1, ELLIPSIS, 45, 46, 47, 48, 49, 50]), (50, 2, 1, [1, ELLIPSIS, 48, 49, 50]), # on_each_side=1, on_ends=3 (1, 1, 3, [1, 2, ELLIPSIS, 48, 49, 50]), (5, 1, 3, [1, 2, 3, 4, 5, 6, ELLIPSIS, 48, 49, 50]), (6, 1, 3, [1, 2, 3, 4, 5, 6, 7, ELLIPSIS, 48, 49, 50]), (7, 1, 3, [1, 2, 3, ELLIPSIS, 6, 7, 8, ELLIPSIS, 48, 49, 50]), (44, 1, 3, [1, 2, 3, ELLIPSIS, 43, 44, 45, ELLIPSIS, 48, 49, 50]), (45, 1, 3, [1, 2, 3, ELLIPSIS, 44, 45, 46, 47, 48, 49, 50]), (46, 1, 3, [1, 2, 3, ELLIPSIS, 45, 46, 47, 48, 49, 50]), (50, 1, 3, [1, 2, 3, ELLIPSIS, 49, 50]), # on_each_side=4, on_ends=0 (1, 4, 0, [1, 2, 3, 4, 5, ELLIPSIS]), (5, 4, 0, [1, 2, 3, 4, 5, 6, 7, 8, 9, ELLIPSIS]), (6, 4, 0, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ELLIPSIS]), (7, 4, 0, [ELLIPSIS, 3, 4, 5, 6, 7, 8, 9, 10, 11, ELLIPSIS]), (44, 4, 0, [ELLIPSIS, 40, 41, 42, 43, 44, 45, 46, 47, 48, ELLIPSIS]), (45, 4, 0, [ELLIPSIS, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50]), (46, 4, 0, [ELLIPSIS, 42, 43, 44, 45, 46, 47, 48, 49, 50]), (50, 4, 0, [ELLIPSIS, 46, 47, 48, 49, 50]), # on_each_side=0, on_ends=1 (1, 0, 1, [1, ELLIPSIS, 50]), (2, 0, 1, [1, 2, ELLIPSIS, 50]), (3, 0, 1, [1, 2, 3, ELLIPSIS, 50]), (4, 0, 1, [1, ELLIPSIS, 4, ELLIPSIS, 50]), (47, 0, 1, [1, ELLIPSIS, 47, ELLIPSIS, 50]), (48, 0, 1, [1, ELLIPSIS, 48, 49, 50]), (49, 0, 1, [1, ELLIPSIS, 49, 50]), (50, 0, 1, [1, ELLIPSIS, 50]), # on_each_side=0, on_ends=0 (1, 0, 0, [1, ELLIPSIS]), (2, 0, 0, [1, 2, ELLIPSIS]), (3, 0, 0, [ELLIPSIS, 3, ELLIPSIS]), (48, 0, 0, [ELLIPSIS, 48, ELLIPSIS]), (49, 0, 0, [ELLIPSIS, 49, 50]), (50, 0, 0, [ELLIPSIS, 50]), ] paginator = Paginator(range(5000), 100) for number, on_each_side, on_ends, expected in tests: with self.subTest(number=number, on_each_side=on_each_side, on_ends=on_ends): page_range = paginator.get_elided_page_range( number, on_each_side=on_each_side, on_ends=on_ends, ) self.assertIsInstance(page_range, collections.abc.Generator) self.assertEqual(list(page_range), expected)
def get(self, request, list_id, add_failed=False, add_succeeded=False): """display a book list""" book_list = get_object_or_404(models.List, id=list_id) book_list.raise_visible_to_user(request.user) if is_api_request(request): return ActivitypubResponse(book_list.to_activity(**request.GET)) query = request.GET.get("q") suggestions = None items = book_list.listitem_set.filter(approved=True).prefetch_related( "user", "book", "book__authors") items = sort_list(request, items) paginated = Paginator(items, PAGE_LENGTH) if query and request.user.is_authenticated: # search for books suggestions = book_search.search( query, filters=[~Q(parent_work__editions__in=book_list.books.all())], ) elif request.user.is_authenticated: # just suggest whatever books are nearby suggestions = request.user.shelfbook_set.filter(~Q( book__in=book_list.books.all())) suggestions = [s.book for s in suggestions[:5]] if len(suggestions) < 5: suggestions += [ s.default_edition for s in models.Work.objects.filter( ~Q(editions__in=book_list.books.all()), ).order_by( "-updated_date") ][:5 - len(suggestions)] page = paginated.get_page(request.GET.get("page")) embed_key = str(book_list.embed_key.hex) embed_url = reverse("embed-list", args=[book_list.id, embed_key]) embed_url = request.build_absolute_uri(embed_url) if request.GET: embed_url = f"{embed_url}?{request.GET.urlencode()}" data = { "list": book_list, "items": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "pending_count": book_list.listitem_set.filter(approved=False).count(), "suggested_books": suggestions, "list_form": forms.ListForm(instance=book_list), "query": query or "", "sort_form": forms.SortListForm(request.GET), "embed_url": embed_url, "add_failed": add_failed, "add_succeeded": add_succeeded, } return TemplateResponse(request, "lists/list.html", data)
def get(self, request, username, shelf_identifier=None): """display a shelf""" user = get_user_from_username(request.user, username) is_self = user == request.user if is_self: shelves = user.shelf_set.all() else: shelves = models.Shelf.privacy_filter( request.user).filter(user=user).all() # get the shelf and make sure the logged in user should be able to see it if shelf_identifier: shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier) shelf.raise_visible_to_user(request.user) books = shelf.books else: # this is a constructed "all books" view, with a fake "shelf" obj FakeShelf = namedtuple( "Shelf", ("identifier", "name", "user", "books", "privacy")) books = ( models.Edition.viewer_aware_objects(request.user).filter( # privacy is ensured because the shelves are already filtered above shelfbook__shelf__in=shelves).distinct()) shelf = FakeShelf("all", _("All books"), user, books, "public") if is_api_request(request) and shelf_identifier: return ActivitypubResponse(shelf.to_activity(**request.GET)) reviews = models.Review.objects if not is_self: reviews = models.Review.privacy_filter(request.user) reviews = reviews.filter( user=user, rating__isnull=False, book__id=OuterRef("id"), deleted=False, ).order_by("-published_date") reading = models.ReadThrough.objects reading = reading.filter( user=user, book__id=OuterRef("id")).order_by("start_date") books = books.annotate(shelved_date=Max("shelfbook__shelved_date")) books = books.annotate( rating=Subquery(reviews.values("rating")[:1]), start_date=Subquery(reading.values("start_date")[:1]), finish_date=Subquery(reading.values("finish_date")[:1]), author=Subquery( models.Book.objects.filter( id=OuterRef("id")).values("authors__name")[:1]), ).prefetch_related("authors") books = sort_books(books, request.GET.get("sort")) paginated = Paginator( books, PAGE_LENGTH, ) page = paginated.get_page(request.GET.get("page")) data = { "user": user, "is_self": is_self, "shelves": shelves, "shelf": shelf, "books": page, "edit_form": forms.ShelfForm(instance=shelf if shelf_identifier else None), "create_form": forms.ShelfForm(), "sort": request.GET.get("sort"), "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), } return TemplateResponse(request, "shelf/shelf.html", data)
class Datagrid(metaclass=DatagridMeta): def __init__( self, queryset, *, parent_model: DjangoModel = None, paginate: bool = True, per_page: int = 20, page: int = 1, more_url: str = None, request: HttpRequest, page_parameter_name: str = "page", ): self.parent_model = parent_model self.page_parameter_name = page_parameter_name self.paginator = Paginator(queryset, per_page) self.page = self.paginator.page(page) self.paginate = paginate self.more_url = more_url self.request = request def __str__(self): """Render the datagrid""" template = loader.get_template(self.template) return template.render(self.context()) @property def template(self): return "ui/datagrid/datagrid.html" def context(self): rows = [] for item in self.page: bound_columns = [] for column in self._meta.columns: bound_columns.append(column.bind(grid=self, model=item)) rows.append(bound_columns) return { "title": get_item_value(None, "title", container=self, exclude=Column), "actions": [action.bind(self) for action in self._meta.actions], "rows": rows, "columns": self._meta.columns, "pagination": { "display": self.paginate, "page_parameter": self.page_parameter_name, "item_label": _("Item") if self.paginator.count == 1 else _("items"), "previous_page_number": self.page.previous_page_number() if self.page.has_previous() else None, "next_page_number": self.page.next_page_number() if self.page.has_next() else None, "current_page_number": self.page.number, "current_page_count": len(self.page), "total_count": self.total_count, "total_page_count": self.total_page_count, "range": self.paginator.get_elided_page_range(self.page.number, on_ends=1), "start_index": self.start_index, "end_index": self.end_index, }, "more_url": self.more_url, } @property def total_count(self): return self.paginator.count @property def total_page_count(self): return self.paginator.num_pages @property def start_index(self): return self.page.start_index() @property def end_index(self): return self.page.end_index() def __len__(self): return self.paginator.count
def get(self, request, list_id): """display a book list""" book_list = get_object_or_404(models.List, id=list_id) if not book_list.visible_to_user(request.user): return HttpResponseNotFound() if is_api_request(request): return ActivitypubResponse(book_list.to_activity(**request.GET)) query = request.GET.get("q") suggestions = None # sort_by shall be "order" unless a valid alternative is given sort_by = request.GET.get("sort_by", "order") if sort_by not in ("order", "title", "rating"): sort_by = "order" # direction shall be "ascending" unless a valid alternative is given direction = request.GET.get("direction", "ascending") if direction not in ("ascending", "descending"): direction = "ascending" directional_sort_by = { "order": "order", "title": "book__title", "rating": "average_rating", }[sort_by] if direction == "descending": directional_sort_by = "-" + directional_sort_by items = book_list.listitem_set if sort_by == "rating": items = items.annotate(average_rating=Avg( Coalesce("book__review__rating", 0.0), output_field=DecimalField(), )) items = items.filter(approved=True).order_by(directional_sort_by) paginated = Paginator(items, PAGE_LENGTH) if query and request.user.is_authenticated: # search for books suggestions = connector_manager.local_search( query, raw=True, filters=[~Q(parent_work__editions__in=book_list.books.all())], ) elif request.user.is_authenticated: # just suggest whatever books are nearby suggestions = request.user.shelfbook_set.filter(~Q( book__in=book_list.books.all())) suggestions = [s.book for s in suggestions[:5]] if len(suggestions) < 5: suggestions += [ s.default_edition for s in models.Work.objects.filter( ~Q(editions__in=book_list.books.all()), ).order_by( "-updated_date") ][:5 - len(suggestions)] page = paginated.get_page(request.GET.get("page")) data = { "list": book_list, "items": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), "pending_count": book_list.listitem_set.filter(approved=False).count(), "suggested_books": suggestions, "list_form": forms.ListForm(instance=book_list), "query": query or "", "sort_form": forms.SortListForm({ "direction": direction, "sort_by": sort_by }), } return TemplateResponse(request, "lists/list.html", data)
def get(self, request, username, shelf_identifier=None): """display a shelf""" user = get_user_from_username(request.user, username) shelves = privacy_filter(request.user, user.shelf_set) # get the shelf and make sure the logged in user should be able to see it if shelf_identifier: try: shelf = user.shelf_set.get(identifier=shelf_identifier) except models.Shelf.DoesNotExist: return HttpResponseNotFound() if not shelf.visible_to_user(request.user): return HttpResponseNotFound() books = shelf.books # this is a constructed "all books" view, with a fake "shelf" obj else: FakeShelf = namedtuple( "Shelf", ("identifier", "name", "user", "books", "privacy")) books = models.Edition.objects.filter( # privacy is ensured because the shelves are already filtered above shelfbook__shelf__in=shelves.all()).distinct() shelf = FakeShelf("all", _("All books"), user, books, "public") if is_api_request(request): return ActivitypubResponse(shelf.to_activity(**request.GET)) reviews = privacy_filter( request.user, models.Review.objects.filter( user=user, rating__isnull=False, book__id=OuterRef("id"), ), ).order_by("-published_date") books = books.annotate(rating=Subquery(reviews.values("rating")[:1])) paginated = Paginator( books.order_by("-updated_date"), PAGE_LENGTH, ) page = paginated.get_page(request.GET.get("page")) data = { "user": user, "is_self": request.user == user, "shelves": shelves.all(), "shelf": shelf, "books": page, "page_range": paginated.get_elided_page_range(page.number, on_each_side=2, on_ends=1), } return TemplateResponse(request, "user/shelf/shelf.html", data)
def get_proper_elided_page_range(p, number, on_each_side=3, on_ends=2): """Paginator get_proper_elided_page_range override""" paginator = Paginator(p.object_list, p.per_page, p.orphans) return paginator.get_elided_page_range(number=number, on_each_side=on_each_side, on_ends=on_ends)