Web bookshelf first draft

This commit is contained in:
2023-10-02 22:58:15 +02:00
parent 3f905877e7
commit 996ddd67ea
6 changed files with 137 additions and 3 deletions

View File

@@ -26,7 +26,7 @@ class BookAdmin(SortableAdminBase, admin.ModelAdmin):
"get_authors", "get_authors",
"get_publisher", "get_publisher",
"publication_year", "publication_year",
"numbers_of_pages" "number_of_pages"
) )
search_fields = ("title", "publisher__name", "authors__last_name") search_fields = ("title", "publisher__name", "authors__last_name")
list_filter = ("publisher__name", "authors") list_filter = ("publisher__name", "authors")

View File

@@ -0,0 +1,18 @@
# Generated by Django 4.2.5 on 2023-10-02 20:38
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("bookshelf", "0003_bookimage"),
]
operations = [
migrations.RenameField(
model_name="book",
old_name="numbers_of_pages",
new_name="number_of_pages",
),
]

View File

@@ -1,6 +1,7 @@
from uuid import uuid4 from uuid import uuid4
from django.db import models from django.db import models
from django.conf import settings from django.conf import settings
from django.urls import reverse
from django_countries.fields import CountryField from django_countries.fields import CountryField
from ckeditor_uploader.fields import RichTextUploadingField from ckeditor_uploader.fields import RichTextUploadingField
@@ -41,7 +42,7 @@ class Book(models.Model):
choices=settings.LANGUAGES, choices=settings.LANGUAGES,
default='en' default='en'
) )
numbers_of_pages = models.SmallIntegerField(null=True, blank=True) number_of_pages = models.SmallIntegerField(null=True, blank=True)
publication_year = models.SmallIntegerField(null=True, blank=True) publication_year = models.SmallIntegerField(null=True, blank=True)
purchase_date = models.DateField(null=True, blank=True) purchase_date = models.DateField(null=True, blank=True)
tags = models.ManyToManyField( tags = models.ManyToManyField(
@@ -58,7 +59,7 @@ class Book(models.Model):
return self.publisher.name return self.publisher.name
# def get_absolute_url(self): # def get_absolute_url(self):
# return reverse("rolling_stock", kwargs={"uuid": self.uuid}) # return reverse("books", kwargs={"uuid": self.uuid})
class BookImage(Image): class BookImage(Image):

View File

@@ -0,0 +1,104 @@
{% extends "cards.html" %}
{% block cards %}
{% for d in data %}
<div class="col">
<div class="card shadow-sm">
{% if d.image.all %}
{# FIXME <a href="{{ d.get_absolute_url }}"> #}
{% for r in d.image.all %}
{% if forloop.first %}<img src="{{ r.image.url }}" alt="Card image cap">{% endif %}
{% endfor %}
{# FIXME </a> #}
{% endif %}
<div class="card-body">
<p class="card-text" style="position: relative;">
<strong>{{ d }}</strong>
{# <a class="stretched-link" href="{{ d.get_absolute_url }}"></a> #}
</p>
{% if d.tags.all %}
<p class="card-text"><small>Tags:</small>
{% for t in d.tags.all %}<a href="{% url 'filtered' _filter="tag" search=t.slug %}" class="badge rounded-pill bg-primary">
{{ t.name }}</a>{# new line is required #}
{% endfor %}
</p>
{% endif %}
<table class="table table-striped">
<thead>
<tr>
<th colspan="2" scope="row">Book</th>
</tr>
</thead>
<tbody class="table-group-divider">
<tr>
<th class="w-33" scope="row">Authors</th>
<td>
<ul class="mb-0 list-unstyled">{% for a in d.authors.all %}<li>{{ a }}</li>{% endfor %}</ul>
</td>
</tr>
<tr>
<th class="w-33" scope="row">Publisher</th>
<td>{{ d.publisher }}</td>
</tr>
<tr>
<th scope="row">Language</th>
<td>{{ d.get_language_display }}</td>
</tr>
<tr>
<th scope="row">Pages</th>
<td>{{ d.number_of_pages }}</td>
</tr>
<tr>
<th scope="row">Year</th>
<td>{{ d.publication_year }}</td>
</tr>
</tbody>
</table>
<div class="d-grid gap-2 mb-1 d-md-block">
{# FIXME <a class="btn btn-sm btn-outline-primary" href="{{ d.get_absolute_url }}">Show all data</a> #}
{% if request.user.is_staff %}<a class="btn btn-sm btn-outline-danger" href="{% url 'admin:bookshelf_book_change' d.pk %}">Edit</a>{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
{% endblock %}
{% block pagination %}
{% if data.has_other_pages %}
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center mt-4 mb-0">
{% if data.has_previous %}
<li class="page-item">
<a class="page-link" href="{% url 'books_pagination' page=data.previous_page_number %}#rolling-stock" tabindex="-1">Previous</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Previous</span>
</li>
{% endif %}
{% for i in page_range %}
{% if data.number == i %}
<li class="page-item active">
<span class="page-link">{{ i }}</span>
</li>
{% else %}
{% if i == data.paginator.ELLIPSIS %}
<li class="page-item"><span class="page-link">{{ i }}</span></li>
{% else %}
<li class="page-item"><a class="page-link" href="{% url 'books_pagination' page=i %}#rolling-stock">{{ i }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
{% if data.has_next %}
<li class="page-item">
<a class="page-link" href="{% url 'books_pagination' page=data.next_page_number %}#rolling-stock" tabindex="-1">Next</a>
</li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Next</span>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endblock %}

View File

@@ -12,6 +12,7 @@ from portal.views import (
Manufacturers, Manufacturers,
Scales, Scales,
Types, Types,
Books,
SearchRoster, SearchRoster,
) )
@@ -54,6 +55,8 @@ urlpatterns = [
path("scales/<int:page>", Types.as_view(), name="scales_pagination"), path("scales/<int:page>", Types.as_view(), name="scales_pagination"),
path("types", Types.as_view(), name="types"), path("types", Types.as_view(), name="types"),
path("types/<int:page>", Types.as_view(), name="types_pagination"), path("types/<int:page>", Types.as_view(), name="types_pagination"),
path("books", Books.as_view(), name="books"),
path("books/<int:page>", Books.as_view(), name="books_pagination"),
path( path(
"search", "search",
SearchRoster.as_view(http_method_names=["post"]), SearchRoster.as_view(http_method_names=["post"]),

View File

@@ -14,6 +14,7 @@ from portal.utils import get_site_conf
from portal.models import Flatpage from portal.models import Flatpage
from roster.models import RollingStock from roster.models import RollingStock
from consist.models import Consist from consist.models import Consist
from bookshelf.models import Book
from metadata.models import Company, Manufacturer, Scale, RollingStockType, Tag from metadata.models import Company, Manufacturer, Scale, RollingStockType, Tag
@@ -340,6 +341,13 @@ class Types(GetData):
self.data = RollingStockType.objects.all() self.data = RollingStockType.objects.all()
class Books(GetData):
def __init__(self):
self.title = "Books"
self.template = "books.html"
self.data = Book.objects.all()
class GetFlatpage(View): class GetFlatpage(View):
def get(self, request, flatpage): def get(self, request, flatpage):
try: try: