diff --git a/catalog/search/views.py b/catalog/search/views.py
index f9ee2b7c..af50aa7c 100644
--- a/catalog/search/views.py
+++ b/catalog/search/views.py
@@ -141,7 +141,7 @@ def search(request):
{
"items": items,
"dup_items": dup_items,
- "pagination": PageLinksGenerator(PAGE_LINK_NUMBER, p, num_pages),
+ "pagination": PageLinksGenerator(p, num_pages, request.GET),
"sites": SiteName.labels,
"hide_category": hide_category,
},
diff --git a/catalog/views.py b/catalog/views.py
index 11ed0da2..164bdc9e 100644
--- a/catalog/views.py
+++ b/catalog/views.py
@@ -157,7 +157,7 @@ def mark_list(request, item_path, item_uuid, following_only=False):
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
page_number = request.GET.get("page", default=1)
marks = paginator.get_page(page_number)
- pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
+ pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET)
return render(
request,
"item_mark_list.html",
@@ -179,7 +179,7 @@ def review_list(request, item_path, item_uuid):
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
page_number = request.GET.get("page", default=1)
reviews = paginator.get_page(page_number)
- pagination = PageLinksGenerator(PAGE_LINK_NUMBER, page_number, paginator.num_pages)
+ pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET)
return render(
request,
"item_review_list.html",
diff --git a/common/static/scss/_common.scss b/common/static/scss/_common.scss
index 39790539..c8e41878 100644
--- a/common/static/scss/_common.scss
+++ b/common/static/scss/_common.scss
@@ -184,3 +184,26 @@ form img {
margin: 0 0.5em;
}
}
+
+.pagination {
+ text-align: center;
+ width: 100%;
+ margin-top: 1em;
+ a {
+ margin: 0 0.3em;
+ }
+ .s, .prev, .next {
+ font-size: 1.4em;
+ }
+ .prev {
+ margin-right: 0.5em;
+ }
+ .next {
+ margin-left: 0.5em;
+ }
+ .current {
+ font-weight: bold;
+ font-size: 1.1em;
+ color: var(--pico-secondary);
+ }
+}
diff --git a/common/static/scss/_legacy.sass b/common/static/scss/_legacy.sass
index 45093622..ed1e6771 100644
--- a/common/static/scss/_legacy.sass
+++ b/common/static/scss/_legacy.sass
@@ -954,57 +954,10 @@ $panel-padding : 0
padding: 0
list-style: none
-.pagination
- // position: absolute
- // bottom: 30px
- // left: 50%
- // transform: translateX(-50%)
- text-align: center
- width: 100%
-
- & &__page-link
- font-weight: normal
- margin: 0 5px
-
- &--current
- font-weight: bold
- font-size: 1.2em
- // text-decoration: underline
- color: $color-secondary
-
- & &__nav-link
- font-size: 1.4em
- margin: 0 2px
-
- $nav-link-edge-margin-width: 18px
-
- &--right-margin
- margin-right: $nav-link-edge-margin-width
-
- &--left-margin
- margin-left: $nav-link-edge-margin-width
-
- &--hidden
- display: none
-
// Small devices (landscape phones, 576px and up)
@media (max-width: $small-devices)
- .pagination
- & &__page-link
- margin: 0 3px
-
- & &__nav-link
- font-size: 1.4em
- margin: 0 2px
-
- $nav-link-edge-margin-width: 10px
-
- &--right-margin
- margin-right: $nav-link-edge-margin-width
-
- &--left-margin
- margin-left: $nav-link-edge-margin-width
+ pass
// Medium devices (tablets, 768px and up)
@media (max-width: $medium-devices)
pass
diff --git a/common/templates/_pagination.html b/common/templates/_pagination.html
index 892dcb18..729d61f3 100644
--- a/common/templates/_pagination.html
+++ b/common/templates/_pagination.html
@@ -1,23 +1,20 @@
diff --git a/common/utils.py b/common/utils.py
index b42de4fb..8c6d6191 100644
--- a/common/utils.py
+++ b/common/utils.py
@@ -1,11 +1,15 @@
import functools
+import re
import uuid
from typing import TYPE_CHECKING
-from django.http import Http404, HttpRequest, HttpResponseRedirect
+from django.db.models import query
+from django.http import Http404, HttpRequest, HttpResponseRedirect, QueryDict
from django.utils import timezone
from django.utils.baseconv import base62
+from .config import PAGE_LINK_NUMBER
+
if TYPE_CHECKING:
from users.models import APIdentity, User
@@ -82,8 +86,19 @@ class PageLinksGenerator:
length -- the number of page links in pagination
"""
- def __init__(self, length: int, current_page: int, total_pages: int):
+ def __init__(
+ self, current_page: int, total_pages: int, query: QueryDict | None = None
+ ):
+ length = PAGE_LINK_NUMBER
current_page = int(current_page)
+ self.query_string = ""
+ if query:
+ q = query.copy()
+ if q.get("page"):
+ q.pop("page")
+ self.query_string = q.urlencode()
+ if self.query_string:
+ self.query_string += "&"
self.current_page = current_page
self.previous_page = current_page - 1 if current_page > 1 else None
self.next_page = current_page + 1 if current_page < total_pages else None
diff --git a/journal/models/rating.py b/journal/models/rating.py
index d5813d6d..5bbc94fe 100644
--- a/journal/models/rating.py
+++ b/journal/models/rating.py
@@ -1,11 +1,12 @@
from datetime import datetime
+from typing import Any
-from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
-from django.db import connection, models
+from django.core.validators import MaxValueValidator, MinValueValidator
+from django.db import models
from django.db.models import Avg, Count, Q
from django.utils.translation import gettext_lazy as _
-from catalog.models import Item, ItemCategory
+from catalog.models import Item
from users.models import APIdentity
from .common import Content
@@ -116,24 +117,22 @@ class Rating(Content):
@staticmethod
def update_item_rating(
- item: Item, owner: APIdentity, rating_grade: int | None, visibility: int = 0
+ item: Item,
+ owner: APIdentity,
+ rating_grade: int | None,
+ visibility: int = 0,
+ created_time: datetime | None = None,
):
if rating_grade and (rating_grade < 1 or rating_grade > 10):
raise ValueError(f"Invalid rating grade: {rating_grade}")
- rating = Rating.objects.filter(owner=owner, item=item).first()
if not rating_grade:
- if rating:
- rating.delete()
- rating = None
- elif rating is None:
- rating = Rating.objects.create(
- owner=owner, item=item, grade=rating_grade, visibility=visibility
- )
- elif rating.grade != rating_grade or rating.visibility != visibility:
- rating.visibility = visibility
- rating.grade = rating_grade
- rating.save()
- return rating
+ Rating.objects.filter(owner=owner, item=item).delete()
+ else:
+ d: dict[str, Any] = {"grade": rating_grade, "visibility": visibility}
+ if created_time:
+ d["created_time"] = created_time
+ r, _ = Rating.objects.update_or_create(owner=owner, item=item, defaults=d)
+ return r
@staticmethod
def get_item_rating(item: Item, owner: APIdentity) -> int | None:
diff --git a/journal/models/shelf.py b/journal/models/shelf.py
index a01db0fe..8d9ced04 100644
--- a/journal/models/shelf.py
+++ b/journal/models/shelf.py
@@ -259,6 +259,15 @@ class ShelfManager:
else:
return qs
+ def get_members(
+ self, shelf_type: ShelfType, item_category: ItemCategory | None = None
+ ):
+ qs = self.shelf_list[shelf_type].members.all()
+ if item_category:
+ return qs.filter(q_item_in_category(item_category))
+ else:
+ return qs
+
# def get_items_on_shelf(self, item_category, shelf_type):
# shelf = (
# self.owner.shelf_set.all()
diff --git a/journal/templates/_sidebar_user_mark_list.html b/journal/templates/_sidebar_user_mark_list.html
index 88339cb6..6cacad7b 100644
--- a/journal/templates/_sidebar_user_mark_list.html
+++ b/journal/templates/_sidebar_user_mark_list.html
@@ -5,52 +5,65 @@