mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-22 16:16:39 +00:00
feat: first version of a book series list by author
This commit is contained in:
parent
788a33ee8a
commit
35d30a41f3
5 changed files with 96 additions and 1 deletions
|
@ -46,7 +46,7 @@
|
|||
<meta itemprop="isPartOf" content="{{ book.series | escape }}">
|
||||
<meta itemprop="volumeNumber" content="{{ book.series_number }}">
|
||||
|
||||
({{ book.series }}{% if book.series_number %} #{{ book.series_number }}{% endif %})
|
||||
(<a href="{% url 'book-series-by' book.authors.first.id %}?series_name={{ book.series }}">{{ book.series }}{% if book.series_number %} #{{ book.series_number }}{% endif %}</a>)
|
||||
{% endif %}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
|
35
bookwyrm/templates/book/series.html
Normal file
35
bookwyrm/templates/book/series.html
Normal file
|
@ -0,0 +1,35 @@
|
|||
{% extends 'layout.html' %}
|
||||
{% load i18n %}
|
||||
{% load book_display_tags %}
|
||||
|
||||
{% block title %}{{ series_name }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="block">
|
||||
<h1 class="title">{{ series_name }}</h1>
|
||||
<div class="subtitle" dir="auto">
|
||||
{% trans "Series by" %} <a
|
||||
href="{{ author.local_path }}"
|
||||
class="author {{ link_class }}"
|
||||
itemprop="author"
|
||||
itemscope
|
||||
itemtype="https://schema.org/Thing"
|
||||
><span
|
||||
itemprop="name"
|
||||
>{{ author.name }}</span></a>
|
||||
</div>
|
||||
|
||||
<div class="columns is-multiline is-mobile">
|
||||
{% for book in books %}
|
||||
{% with book=book %}
|
||||
<div class="column is-one-fifth-tablet is-half-mobile is-flex is-flex-direction-column">
|
||||
<div class="is-flex-grow-1 mb-3">
|
||||
<span class="subtitle">{% if book.series_number %}Book {{ book.series_number }}{% else %}Unsorted Book{% endif %}</span>
|
||||
{% include 'landing/small-book.html' with book=book %}
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -610,6 +610,7 @@ urlpatterns = [
|
|||
# books
|
||||
re_path(rf"{BOOK_PATH}(.json)?/?$", views.Book.as_view(), name="book"),
|
||||
re_path(rf"{BOOK_PATH}{regex.SLUG}/?$", views.Book.as_view(), name="book"),
|
||||
re_path(r"^series/by/(?P<author_id>\d+)/?$", views.BookSeriesBy.as_view(), name="book-series-by"),
|
||||
re_path(
|
||||
rf"{BOOK_PATH}/(?P<user_statuses>review|comment|quote)/?$",
|
||||
views.Book.as_view(),
|
||||
|
|
|
@ -50,6 +50,7 @@ from .books.books import (
|
|||
add_description,
|
||||
resolve_book,
|
||||
)
|
||||
from .books.series import BookSeriesBy
|
||||
from .books.books import update_book_from_remote
|
||||
from .books.edit_book import (
|
||||
EditBook,
|
||||
|
|
58
bookwyrm/views/books/series.py
Normal file
58
bookwyrm/views/books/series.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
""" books belonging to the same series """
|
||||
from django.views import View
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template.response import TemplateResponse
|
||||
|
||||
from bookwyrm.views.helpers import is_api_request
|
||||
from bookwyrm import models
|
||||
from bookwyrm.settings import PAGE_LENGTH
|
||||
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
class BookSeriesBy(View):
|
||||
def get(self, request, author_id, **kwargs):
|
||||
"""lists all books in a series"""
|
||||
series_name = request.GET.get("series_name")
|
||||
|
||||
if is_api_request(request):
|
||||
pass
|
||||
|
||||
author = get_object_or_404(models.Author, id=author_id)
|
||||
|
||||
results = (
|
||||
models.Edition.objects.filter(authors=author, series=series_name)
|
||||
)
|
||||
|
||||
# when there are multiple editions of the same work, pick the closest
|
||||
editions_of_work = results.values_list("parent_work__id", flat=True).distinct()
|
||||
|
||||
# filter out multiple editions of the same work
|
||||
numbered_books = []
|
||||
dated_books = []
|
||||
unsortable_books = []
|
||||
for work_id in set(editions_of_work):
|
||||
result = (
|
||||
results.filter(parent_work=work_id)
|
||||
.order_by("-edition_rank")
|
||||
.first()
|
||||
)
|
||||
if result.series_number:
|
||||
numbered_books.append(result)
|
||||
elif result.first_published_date or result.published_date:
|
||||
dated_books.append(result)
|
||||
else:
|
||||
unsortable_books.append(result)
|
||||
|
||||
list_results = (
|
||||
sorted(numbered_books, key=lambda book: book.series_number) +
|
||||
sorted(dated_books, key=lambda book: book.first_published_date if book.first_published_date else book.published_date) +
|
||||
sorted(unsortable_books, key=lambda book: book.sort_title)
|
||||
)
|
||||
|
||||
data = {
|
||||
"series_name": series_name,
|
||||
"author": author,
|
||||
"books": list_results,
|
||||
}
|
||||
|
||||
return TemplateResponse(request, "book/series.html", data)
|
Loading…
Reference in a new issue