sort marks by rating
This commit is contained in:
parent
1e3e409a7e
commit
c7445f8f61
15 changed files with 170 additions and 168 deletions
|
@ -141,7 +141,7 @@ def search(request):
|
||||||
{
|
{
|
||||||
"items": items,
|
"items": items,
|
||||||
"dup_items": dup_items,
|
"dup_items": dup_items,
|
||||||
"pagination": PageLinksGenerator(PAGE_LINK_NUMBER, p, num_pages),
|
"pagination": PageLinksGenerator(p, num_pages, request.GET),
|
||||||
"sites": SiteName.labels,
|
"sites": SiteName.labels,
|
||||||
"hide_category": hide_category,
|
"hide_category": hide_category,
|
||||||
},
|
},
|
||||||
|
|
|
@ -157,7 +157,7 @@ def mark_list(request, item_path, item_uuid, following_only=False):
|
||||||
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
||||||
page_number = request.GET.get("page", default=1)
|
page_number = request.GET.get("page", default=1)
|
||||||
marks = paginator.get_page(page_number)
|
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(
|
return render(
|
||||||
request,
|
request,
|
||||||
"item_mark_list.html",
|
"item_mark_list.html",
|
||||||
|
@ -179,7 +179,7 @@ def review_list(request, item_path, item_uuid):
|
||||||
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
paginator = Paginator(queryset, NUM_REVIEWS_ON_LIST_PAGE)
|
||||||
page_number = request.GET.get("page", default=1)
|
page_number = request.GET.get("page", default=1)
|
||||||
reviews = paginator.get_page(page_number)
|
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(
|
return render(
|
||||||
request,
|
request,
|
||||||
"item_review_list.html",
|
"item_review_list.html",
|
||||||
|
|
|
@ -184,3 +184,26 @@ form img {
|
||||||
margin: 0 0.5em;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -954,57 +954,10 @@ $panel-padding : 0
|
||||||
padding: 0
|
padding: 0
|
||||||
list-style: none
|
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)
|
// Small devices (landscape phones, 576px and up)
|
||||||
@media (max-width: $small-devices)
|
@media (max-width: $small-devices)
|
||||||
.pagination
|
pass
|
||||||
& &__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
|
|
||||||
// Medium devices (tablets, 768px and up)
|
// Medium devices (tablets, 768px and up)
|
||||||
@media (max-width: $medium-devices)
|
@media (max-width: $medium-devices)
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,23 +1,20 @@
|
||||||
<div class="pagination">
|
<div class="pagination">
|
||||||
{% if pagination.has_prev %}
|
{% if pagination.has_prev %}
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page=1"
|
<a href="?{{ pagination.query_string }}page=1" class="s">«</a>
|
||||||
class="pagination__nav-link pagination__nav-link">«</a>
|
<a href="?{{ pagination.query_string }}page={{ pagination.previous_page }}"
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page={{ pagination.previous_page }}"
|
class="prev">‹</a>
|
||||||
class="pagination__nav-link pagination__nav-link--right-margin pagination__nav-link">‹</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% for page in pagination.page_range %}
|
{% for page in pagination.page_range %}
|
||||||
{% if page == pagination.current_page %}
|
{% if page == pagination.current_page %}
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page={{ page }}"
|
<a href="?{{ pagination.query_string }}page={{ page }}" class="current">{{ page }}</a>
|
||||||
class="pagination__page-link pagination__page-link--current">{{ page }}</a>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page={{ page }}"
|
<a href="?{{ pagination.query_string }}page={{ page }}">{{ page }}</a>
|
||||||
class="pagination__page-link">{{ page }}</a>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if pagination.has_next %}
|
{% if pagination.has_next %}
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page={{ pagination.next_page }}"
|
<a href="?{{ pagination.query_string }}page={{ pagination.next_page }}"
|
||||||
class="pagination__nav-link pagination__nav-link--left-margin">›</a>
|
class="next">›</a>
|
||||||
<a href="?{% if request.GET.t %}t={{ request.GET.t }}&{% endif %}page={{ pagination.last_page }}"
|
<a href="?{{ pagination.query_string }}page={{ pagination.last_page }}"
|
||||||
class="pagination__nav-link">»</a>
|
class="s">»</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
import functools
|
import functools
|
||||||
|
import re
|
||||||
import uuid
|
import uuid
|
||||||
from typing import TYPE_CHECKING
|
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 import timezone
|
||||||
from django.utils.baseconv import base62
|
from django.utils.baseconv import base62
|
||||||
|
|
||||||
|
from .config import PAGE_LINK_NUMBER
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from users.models import APIdentity, User
|
from users.models import APIdentity, User
|
||||||
|
|
||||||
|
@ -82,8 +86,19 @@ class PageLinksGenerator:
|
||||||
length -- the number of page links in pagination
|
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)
|
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.current_page = current_page
|
||||||
self.previous_page = current_page - 1 if current_page > 1 else None
|
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
|
self.next_page = current_page + 1 if current_page < total_pages else None
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from django.core.validators import MaxValueValidator, MinValueValidator, RegexValidator
|
from django.core.validators import MaxValueValidator, MinValueValidator
|
||||||
from django.db import connection, models
|
from django.db import models
|
||||||
from django.db.models import Avg, Count, Q
|
from django.db.models import Avg, Count, Q
|
||||||
from django.utils.translation import gettext_lazy as _
|
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 users.models import APIdentity
|
||||||
|
|
||||||
from .common import Content
|
from .common import Content
|
||||||
|
@ -116,24 +117,22 @@ class Rating(Content):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_item_rating(
|
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):
|
if rating_grade and (rating_grade < 1 or rating_grade > 10):
|
||||||
raise ValueError(f"Invalid rating grade: {rating_grade}")
|
raise ValueError(f"Invalid rating grade: {rating_grade}")
|
||||||
rating = Rating.objects.filter(owner=owner, item=item).first()
|
|
||||||
if not rating_grade:
|
if not rating_grade:
|
||||||
if rating:
|
Rating.objects.filter(owner=owner, item=item).delete()
|
||||||
rating.delete()
|
else:
|
||||||
rating = None
|
d: dict[str, Any] = {"grade": rating_grade, "visibility": visibility}
|
||||||
elif rating is None:
|
if created_time:
|
||||||
rating = Rating.objects.create(
|
d["created_time"] = created_time
|
||||||
owner=owner, item=item, grade=rating_grade, visibility=visibility
|
r, _ = Rating.objects.update_or_create(owner=owner, item=item, defaults=d)
|
||||||
)
|
return r
|
||||||
elif rating.grade != rating_grade or rating.visibility != visibility:
|
|
||||||
rating.visibility = visibility
|
|
||||||
rating.grade = rating_grade
|
|
||||||
rating.save()
|
|
||||||
return rating
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_item_rating(item: Item, owner: APIdentity) -> int | None:
|
def get_item_rating(item: Item, owner: APIdentity) -> int | None:
|
||||||
|
|
|
@ -259,6 +259,15 @@ class ShelfManager:
|
||||||
else:
|
else:
|
||||||
return qs
|
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):
|
# def get_items_on_shelf(self, item_category, shelf_type):
|
||||||
# shelf = (
|
# shelf = (
|
||||||
# self.owner.shelf_set.all()
|
# self.owner.shelf_set.all()
|
||||||
|
|
|
@ -5,52 +5,65 @@
|
||||||
<section class="filter">
|
<section class="filter">
|
||||||
<script>
|
<script>
|
||||||
function filter() {
|
function filter() {
|
||||||
location = '{{ user.identity.url }}' + $('#shelf')[0].value + '/' + $('#category')[0].value + '/' + ( $('#year')[0].value ? $('#year')[0].value + '/' : '' );
|
var q = [];
|
||||||
|
if ($('#year')[0].value) {
|
||||||
|
q.push('year=' + $('#year')[0].value)
|
||||||
|
}
|
||||||
|
if ($('#sort')[0].value) {
|
||||||
|
q.push('sort=' + $('#sort')[0].value)
|
||||||
|
}
|
||||||
|
location = '{{ user.identity.url }}' + $('#shelf')[0].value + '/' + $('#category')[0].value + '/' + (q.length ? '?' + q.join('&') : '')
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<form role="search" method="get" action="">
|
<form method="get" action="">
|
||||||
<select name="year" id="year" onchange="filter()">
|
<fieldset role="search" style="width: 100%; padding;">
|
||||||
<option value="">全部</option>
|
<select name="shelf" id="shelf" onchange="filter()">
|
||||||
{% for y in years %}
|
{% for typ, label in shelf_labels %}
|
||||||
<option value="{{ y }}" {% if y == year %}selected{% endif %}>{{ y }}</option>
|
{% if label %}
|
||||||
{% endfor %}
|
<option {% if typ in request.path %}selected{% endif %} value="{{ typ }}">{{ label }}</option>
|
||||||
</select>
|
{% endif %}
|
||||||
<select name="shelf" id="shelf" onchange="filter()">
|
{% endfor %}
|
||||||
{% for typ, label in shelf_labels %}
|
<option {% if '/reviews/' in request.path %}selected{% endif %}
|
||||||
{% if label %}
|
value="reviews">评论</option>
|
||||||
<option {% if typ in request.path %}selected{% endif %} value="{{ typ }}">{{ label }}</option>
|
</select>
|
||||||
|
<select name="category" id="category" onchange="filter()">
|
||||||
|
{% visible_categories as cats %}
|
||||||
|
{% if 'book' in cats %}
|
||||||
|
<option {% if '/book/' in request.path %}selected{% endif %} value="book">书籍</option>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% if 'movie' in cats %}
|
||||||
<option {% if '/reviews/' in request.path %}selected{% endif %}
|
<option {% if '/movie/' in request.path %}selected{% endif %} value="movie">电影</option>
|
||||||
value="reviews">评论</option>
|
{% endif %}
|
||||||
</select>
|
{% if 'tv' in cats %}
|
||||||
<select name="category" id="category" onchange="filter()">
|
<option {% if '/tv/' in request.path %}selected{% endif %} value="tv">剧集</option>
|
||||||
{% visible_categories as cats %}
|
{% endif %}
|
||||||
{% if 'book' in cats %}
|
{% if 'podcast' in cats %}
|
||||||
<option {% if '/book/' in request.path %}selected{% endif %} value="book">书籍</option>
|
<option {% if '/podcast/' in request.path %}selected{% endif %}
|
||||||
{% endif %}
|
value="podcast">播客</option>
|
||||||
{% if 'movie' in cats %}
|
{% endif %}
|
||||||
<option {% if '/movie/' in request.path %}selected{% endif %} value="movie">电影</option>
|
{% if 'music' in cats %}
|
||||||
{% endif %}
|
<option {% if '/music/' in request.path %}selected{% endif %} value="music">音乐</option>
|
||||||
{% if 'tv' in cats %}
|
{% endif %}
|
||||||
<option {% if '/tv/' in request.path %}selected{% endif %} value="tv">剧集</option>
|
{% if 'game' in cats %}
|
||||||
{% endif %}
|
<option {% if '/game/' in request.path %}selected{% endif %} value="game">游戏</option>
|
||||||
{% if 'podcast' in cats %}
|
{% endif %}
|
||||||
<option {% if '/podcast/' in request.path %}selected{% endif %}
|
{% if 'performance' in cats %}
|
||||||
value="podcast">播客</option>
|
<option {% if '/performance/' in request.path %}selected{% endif %}
|
||||||
{% endif %}
|
value="performance">演出</option>
|
||||||
{% if 'music' in cats %}
|
{% endif %}
|
||||||
<option {% if '/music/' in request.path %}selected{% endif %} value="music">音乐</option>
|
</select>
|
||||||
{% endif %}
|
<select name="year" id="year" onchange="filter()">
|
||||||
{% if 'game' in cats %}
|
<option value="">全部</option>
|
||||||
<option {% if '/game/' in request.path %}selected{% endif %} value="game">游戏</option>
|
{% for y in years %}
|
||||||
{% endif %}
|
<option value="{{ y }}" {% if y == year %}selected{% endif %}>{{ y }}</option>
|
||||||
{% if 'performance' in cats %}
|
{% endfor %}
|
||||||
<option {% if '/performance/' in request.path %}selected{% endif %}
|
</select>
|
||||||
value="performance">演出</option>
|
<select name="sort" id="sort" onchange="filter()">
|
||||||
{% endif %}
|
<option value="" disabled>排列顺序</option>
|
||||||
</select>
|
<option value="">时间</option>
|
||||||
|
<option value="rating" {% if 'rating' == sort %}selected{% endif %}>评分</option>
|
||||||
|
</select>
|
||||||
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
<!--
|
<!--
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
|
@ -101,15 +101,6 @@ urlpatterns = [
|
||||||
user_mark_list,
|
user_mark_list,
|
||||||
name="user_mark_list",
|
name="user_mark_list",
|
||||||
),
|
),
|
||||||
re_path(
|
|
||||||
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/(?P<shelf_type>"
|
|
||||||
+ _get_all_shelf_types()
|
|
||||||
+ ")/(?P<item_category>"
|
|
||||||
+ _get_all_categories()
|
|
||||||
+ r")/(?P<year>\d+)/$",
|
|
||||||
user_mark_list,
|
|
||||||
name="user_mark_list_year",
|
|
||||||
),
|
|
||||||
re_path(
|
re_path(
|
||||||
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/reviews/(?P<item_category>"
|
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/reviews/(?P<item_category>"
|
||||||
+ _get_all_categories()
|
+ _get_all_categories()
|
||||||
|
@ -117,13 +108,6 @@ urlpatterns = [
|
||||||
user_review_list,
|
user_review_list,
|
||||||
name="user_review_list",
|
name="user_review_list",
|
||||||
),
|
),
|
||||||
re_path(
|
|
||||||
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/reviews/(?P<item_category>"
|
|
||||||
+ _get_all_categories()
|
|
||||||
+ r")/(?P<year>\d+)/$",
|
|
||||||
user_review_list,
|
|
||||||
name="user_review_list_year",
|
|
||||||
),
|
|
||||||
re_path(
|
re_path(
|
||||||
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/tags/(?P<tag_title>.+)/$",
|
r"^users/(?P<user_name>[~A-Za-z0-9_\-.@]+)/tags/(?P<tag_title>.+)/$",
|
||||||
user_tag_member_list,
|
user_tag_member_list,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import datetime
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDenied
|
from django.core.exceptions import BadRequest, ObjectDoesNotExist, PermissionDenied
|
||||||
from django.core.paginator import Paginator
|
from django.core.paginator import Paginator
|
||||||
from django.db.models import Min
|
from django.db.models import F, Min, OuterRef, Subquery
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
@ -57,12 +57,15 @@ def render_list(
|
||||||
item_category=None,
|
item_category=None,
|
||||||
tag_title=None,
|
tag_title=None,
|
||||||
year=None,
|
year=None,
|
||||||
|
sort="time",
|
||||||
):
|
):
|
||||||
target = request.target_identity
|
target = request.target_identity
|
||||||
viewer = request.user.identity
|
viewer = request.user.identity
|
||||||
tag = None
|
tag = None
|
||||||
|
sort = request.GET.get("sort")
|
||||||
|
year = request.GET.get("year")
|
||||||
if type == "mark" and shelf_type:
|
if type == "mark" and shelf_type:
|
||||||
queryset = target.shelf_manager.get_latest_members(shelf_type, item_category)
|
queryset = target.shelf_manager.get_members(shelf_type, item_category)
|
||||||
elif type == "tagmember":
|
elif type == "tagmember":
|
||||||
tag = Tag.objects.filter(owner=target, title=tag_title).first()
|
tag = Tag.objects.filter(owner=target, title=tag_title).first()
|
||||||
if not tag:
|
if not tag:
|
||||||
|
@ -74,6 +77,15 @@ def render_list(
|
||||||
queryset = Review.objects.filter(q_item_in_category(item_category))
|
queryset = Review.objects.filter(q_item_in_category(item_category))
|
||||||
else:
|
else:
|
||||||
raise BadRequest()
|
raise BadRequest()
|
||||||
|
if sort == "rating":
|
||||||
|
rating = Rating.objects.filter(
|
||||||
|
owner_id=OuterRef("owner_id"), item_id=OuterRef("item_id")
|
||||||
|
)
|
||||||
|
queryset = queryset.alias(
|
||||||
|
rating_grade=Subquery(rating.values("grade"))
|
||||||
|
).order_by(F("rating_grade").desc(nulls_last=True))
|
||||||
|
else:
|
||||||
|
queryset = queryset.order_by("-created_time")
|
||||||
start_date = queryset.aggregate(Min("created_time"))["created_time__min"]
|
start_date = queryset.aggregate(Min("created_time"))["created_time__min"]
|
||||||
if start_date:
|
if start_date:
|
||||||
start_year = start_date.year
|
start_year = start_date.year
|
||||||
|
@ -81,16 +93,14 @@ def render_list(
|
||||||
years = reversed(range(start_year, current_year + 1))
|
years = reversed(range(start_year, current_year + 1))
|
||||||
else:
|
else:
|
||||||
years = []
|
years = []
|
||||||
queryset = queryset.filter(
|
queryset = queryset.filter(q_owned_piece_visible_to_user(request.user, target))
|
||||||
q_owned_piece_visible_to_user(request.user, target)
|
|
||||||
).order_by("-created_time")
|
|
||||||
if year:
|
if year:
|
||||||
year = int(year)
|
year = int(year)
|
||||||
queryset = queryset.filter(created_time__year=year)
|
queryset = queryset.filter(created_time__year=year)
|
||||||
paginator = Paginator(queryset, PAGE_SIZE)
|
paginator = Paginator(queryset, PAGE_SIZE)
|
||||||
page_number = int(request.GET.get("page", default=1))
|
page_number = int(request.GET.get("page", default=1))
|
||||||
members = paginator.get_page(page_number)
|
members = paginator.get_page(page_number)
|
||||||
pagination = PageLinksGenerator(PAGE_SIZE, page_number, paginator.num_pages)
|
pagination = PageLinksGenerator(page_number, paginator.num_pages, request.GET)
|
||||||
shelf_labels = get_shelf_labels_for_category(item_category) if item_category else []
|
shelf_labels = get_shelf_labels_for_category(item_category) if item_category else []
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
|
@ -103,6 +113,7 @@ def render_list(
|
||||||
"pagination": pagination,
|
"pagination": pagination,
|
||||||
"years": years,
|
"years": years,
|
||||||
"year": year,
|
"year": year,
|
||||||
|
"sort": sort,
|
||||||
"shelf": shelf_type,
|
"shelf": shelf_type,
|
||||||
"shelf_labels": shelf_labels,
|
"shelf_labels": shelf_labels,
|
||||||
"category": item_category,
|
"category": item_category,
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.utils.dateparse import parse_datetime
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from catalog.models import *
|
from catalog.models import *
|
||||||
from common.utils import AuthedHttpRequest, PageLinksGenerator, get_uuid_or_404
|
from common.utils import AuthedHttpRequest, get_uuid_or_404
|
||||||
from mastodon.api import boost_toot_later, share_comment
|
from mastodon.api import boost_toot_later, share_comment
|
||||||
from takahe.utils import Takahe
|
from takahe.utils import Takahe
|
||||||
|
|
||||||
|
@ -184,14 +184,7 @@ def comment(request: AuthedHttpRequest, item_uuid):
|
||||||
raise BadRequest()
|
raise BadRequest()
|
||||||
|
|
||||||
|
|
||||||
def user_mark_list(
|
def user_mark_list(request: AuthedHttpRequest, user_name, shelf_type, item_category):
|
||||||
request: AuthedHttpRequest, user_name, shelf_type, item_category, year=None
|
|
||||||
):
|
|
||||||
return render_list(
|
return render_list(
|
||||||
request,
|
request, user_name, "mark", shelf_type=shelf_type, item_category=item_category
|
||||||
user_name,
|
|
||||||
"mark",
|
|
||||||
shelf_type=shelf_type,
|
|
||||||
item_category=item_category,
|
|
||||||
year=year,
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -5,12 +5,7 @@ from django.urls import reverse
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
|
|
||||||
from common.utils import (
|
from common.utils import AuthedHttpRequest, get_uuid_or_404, target_identity_required
|
||||||
AuthedHttpRequest,
|
|
||||||
PageLinksGenerator,
|
|
||||||
get_uuid_or_404,
|
|
||||||
target_identity_required,
|
|
||||||
)
|
|
||||||
from mastodon.api import boost_toot_later
|
from mastodon.api import boost_toot_later
|
||||||
from takahe.utils import Takahe
|
from takahe.utils import Takahe
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from django.views.decorators.http import require_http_methods
|
from django.views.decorators.http import require_http_methods
|
||||||
|
|
||||||
from catalog.models import *
|
from catalog.models import *
|
||||||
from common.utils import AuthedHttpRequest, PageLinksGenerator, get_uuid_or_404
|
from common.utils import AuthedHttpRequest, get_uuid_or_404
|
||||||
from journal.models.renderers import convert_leading_space_in_md, render_md
|
from journal.models.renderers import convert_leading_space_in_md, render_md
|
||||||
from users.models.apidentity import APIdentity
|
from users.models.apidentity import APIdentity
|
||||||
|
|
||||||
|
@ -97,10 +97,8 @@ def review_edit(request: AuthedHttpRequest, item_uuid, review_uuid=None):
|
||||||
raise BadRequest()
|
raise BadRequest()
|
||||||
|
|
||||||
|
|
||||||
def user_review_list(request, user_name, item_category, year=None):
|
def user_review_list(request, user_name, item_category):
|
||||||
return render_list(
|
return render_list(request, user_name, "review", item_category=item_category)
|
||||||
request, user_name, "review", item_category=item_category, year=None
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
MAX_ITEM_PER_TYPE = 10
|
MAX_ITEM_PER_TYPE = 10
|
||||||
|
|
|
@ -1,2 +1,14 @@
|
||||||
|
User-agent: CCBot
|
||||||
|
Disallow: /review/
|
||||||
|
|
||||||
User-agent: GPTBot
|
User-agent: GPTBot
|
||||||
Disallow: /review/
|
Disallow: /review/
|
||||||
|
|
||||||
|
User-agent: Google-Extended
|
||||||
|
Disallow: /review/
|
||||||
|
|
||||||
|
User-agent: FacebookBot
|
||||||
|
Disallow: /review/
|
||||||
|
|
||||||
|
User-agent: Omgilibot
|
||||||
|
Disallow: /review/
|
||||||
|
|
Loading…
Add table
Reference in a new issue