From 119d25ede6c9afbca02f7e391cb842dfd04582a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Wed, 27 Nov 2024 23:07:43 +0100 Subject: [PATCH 01/13] WIP: implement catalogue type of books --- ram/bookshelf/admin.py | 8 +- .../0016_basebook_book_catalogue.py | 128 ++++++++++++++++++ ram/bookshelf/models.py | 58 +++++--- 3 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 ram/bookshelf/migrations/0016_basebook_book_catalogue.py diff --git a/ram/bookshelf/admin.py b/ram/bookshelf/admin.py index 5615472..58de299 100644 --- a/ram/bookshelf/admin.py +++ b/ram/bookshelf/admin.py @@ -1,11 +1,13 @@ from django.contrib import admin from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin -from bookshelf.models import BookProperty, BookImage, Book, Author, Publisher +from bookshelf.models import ( + BaseBookProperty, BaseBookImage, Book, Author, Publisher +) class BookImageInline(SortableInlineAdminMixin, admin.TabularInline): - model = BookImage + model = BaseBookImage min_num = 0 extra = 0 readonly_fields = ("image_thumbnail",) @@ -13,7 +15,7 @@ class BookImageInline(SortableInlineAdminMixin, admin.TabularInline): class BookPropertyInline(admin.TabularInline): - model = BookProperty + model = BaseBookProperty min_num = 0 extra = 0 autocomplete_fields = ("property",) diff --git a/ram/bookshelf/migrations/0016_basebook_book_catalogue.py b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py new file mode 100644 index 0000000..fc0d8c1 --- /dev/null +++ b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py @@ -0,0 +1,128 @@ +# Generated by Django 5.1.2 on 2024-11-27 16:35 + +import django.db.models.deletion +from django.db import migrations, models + + +def nil(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookshelf", "0015_alter_book_authors"), + ("metadata", "0019_alter_scale_gauge"), + ] + + operations = [ + migrations.RenameModel( + old_name="BookImage", + new_name="BaseBookImage", + ), + migrations.RenameModel( + old_name="BookProperty", + new_name="BaseBookProperty", + ), + migrations.RenameModel( + old_name="Book", + new_name="BaseBook", + ), + migrations.RenameField( + model_name="basebook", + old_name="title", + new_name="old_title", + ), + migrations.RenameField( + model_name="basebook", + old_name="authors", + new_name="old_authors", + ), + migrations.RenameField( + model_name="basebook", + old_name="publisher", + new_name="old_publisher", + ), + migrations.CreateModel( + name="Book", + fields=[ + ( + "basebook_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="bookshelf.basebook", + ), + ), + ("title", models.CharField(max_length=200)), + ( + "authors", + models.ManyToManyField( + blank=True, + to="bookshelf.author" + ), + ), + ( + "publisher", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="bookshelf.publisher" + ), + ), + ], + options={ + "ordering": ["title"], + }, + bases=("bookshelf.basebook",), + ), + migrations.CreateModel( + name="Catalog", + fields=[ + ( + "basebook_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="bookshelf.basebook", + ), + ), + ("years", models.CharField(max_length=12)), + ( + "manufacturer", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="metadata.manufacturer", + ), + ), + ("scales", models.ManyToManyField(to="metadata.scale")), + ], + options={ + "ordering": ["manufacturer", "publication_year"], + }, + bases=("bookshelf.basebook",), + ), + migrations.RunPython( + nil, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveField( + model_name="basebook", + name="old_title", + ), + migrations.RemoveField( + model_name="basebook", + name="old_authors", + ), + migrations.RemoveField( + model_name="basebook", + name="old_publisher", + ), + ] diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index 46e036b..af0643e 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -10,6 +10,7 @@ from metadata.models import Tag from ram.utils import DeduplicatedStorage from ram.models import BaseModel, Image, PropertyInstance +from metadata.models import Scale, Manufacturer class Publisher(models.Model): @@ -38,10 +39,7 @@ def short_name(self): return f"{self.last_name} {self.first_name[0]}." -class Book(BaseModel): - title = models.CharField(max_length=200) - authors = models.ManyToManyField(Author, blank=True) - publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) +class BaseBook(BaseModel): ISBN = models.CharField(max_length=17, blank=True) # 13 + dashes language = models.CharField( max_length=7, @@ -56,15 +54,6 @@ class Book(BaseModel): Tag, related_name="bookshelf", blank=True ) - class Meta: - ordering = ["title"] - - def __str__(self): - return self.title - - def publisher_name(self): - return self.publisher.name - def get_absolute_url(self): return reverse("book", kwargs={"uuid": self.uuid}) @@ -75,7 +64,7 @@ def delete(self, *args, **kwargs): ), ignore_errors=True ) - super(Book, self).delete(*args, **kwargs) + super(BaseBook, self).delete(*args, **kwargs) def book_image_upload(instance, filename): @@ -87,9 +76,9 @@ def book_image_upload(instance, filename): ) -class BookImage(Image): +class BaseBookImage(Image): book = models.ForeignKey( - Book, on_delete=models.CASCADE, related_name="image" + BaseBook, on_delete=models.CASCADE, related_name="image" ) image = models.ImageField( upload_to=book_image_upload, @@ -97,11 +86,44 @@ class BookImage(Image): ) -class BookProperty(PropertyInstance): +class BaseBookProperty(PropertyInstance): book = models.ForeignKey( - Book, + BaseBook, on_delete=models.CASCADE, null=False, blank=False, related_name="property", ) + + +class Book(BaseBook): + title = models.CharField(max_length=200) + authors = models.ManyToManyField(Author, blank=True) + publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) + + class Meta: + ordering = ["title"] + + def __str__(self): + return self.title + + def publisher_name(self): + return self.publisher.name + + +class Catalog(BaseBook): + manufacturer = models.ForeignKey( + Manufacturer, + on_delete=models.CASCADE, + null=True, + blank=True, + ) + years = models.CharField(max_length=12) + scales = models.ManyToManyField(Scale) + + class Meta: + ordering = ["manufacturer", "publication_year"] + + def __str__(self): + scales = "/".join([s.scale for s in self.scales.all()]) + return "%s %s %s" % (self.manufacturer.name, self.years, scales) From b5b88f771440ce11cdcfdde1d6873d842d9d7fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Wed, 27 Nov 2024 23:14:44 +0100 Subject: [PATCH 02/13] Minor change to Image model Meta --- ram/ram/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/ram/ram/models.py b/ram/ram/models.py index 3a02b2c..8e5b1b9 100644 --- a/ram/ram/models.py +++ b/ram/ram/models.py @@ -65,6 +65,7 @@ def __str__(self): class Meta: abstract = True ordering = ["order"] + verbose_name_plural = "Images" objects = PublicManager() From 21c99f73c368dd8f6fc21b1c550a9073f963f160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Fri, 29 Nov 2024 23:16:31 +0100 Subject: [PATCH 03/13] Implement Book data migration --- .../0016_basebook_book_catalogue.py | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/ram/bookshelf/migrations/0016_basebook_book_catalogue.py b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py index fc0d8c1..0be21a2 100644 --- a/ram/bookshelf/migrations/0016_basebook_book_catalogue.py +++ b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py @@ -4,8 +4,16 @@ from django.db import migrations, models -def nil(apps, schema_editor): - pass +def basebook_to_book(apps, schema_editor): + basebook = apps.get_model("bookshelf", "BaseBook") + book = apps.get_model("bookshelf", "Book") + for row in basebook.objects.all(): + b = book.objects.create( + basebook_ptr=row, + title=row.old_title, + publisher=row.old_publisher, + ) + b.authors.set(row.old_authors.all()) class Migration(migrations.Migration): @@ -16,6 +24,10 @@ class Migration(migrations.Migration): ] operations = [ + migrations.AlterModelOptions( + name="Book", + options={"ordering": ["creation_time"]}, + ), migrations.RenameModel( old_name="BookImage", new_name="BaseBookImage", @@ -43,6 +55,10 @@ class Migration(migrations.Migration): old_name="publisher", new_name="old_publisher", ), + migrations.AlterModelOptions( + name="basebookimage", + options={"ordering": ["order"], "verbose_name_plural": "Images"}, + ), migrations.CreateModel( name="Book", fields=[ @@ -76,7 +92,22 @@ class Migration(migrations.Migration): options={ "ordering": ["title"], }, - bases=("bookshelf.basebook",), + ), + migrations.RunPython( + basebook_to_book, + reverse_code=migrations.RunPython.noop + ), + migrations.RemoveField( + model_name="basebook", + name="old_title", + ), + migrations.RemoveField( + model_name="basebook", + name="old_authors", + ), + migrations.RemoveField( + model_name="basebook", + name="old_publisher", ), migrations.CreateModel( name="Catalog", @@ -109,20 +140,4 @@ class Migration(migrations.Migration): }, bases=("bookshelf.basebook",), ), - migrations.RunPython( - nil, - reverse_code=migrations.RunPython.noop - ), - migrations.RemoveField( - model_name="basebook", - name="old_title", - ), - migrations.RemoveField( - model_name="basebook", - name="old_authors", - ), - migrations.RemoveField( - model_name="basebook", - name="old_publisher", - ), ] From 1a3b30ace3735b596eb5452d20f965b588a47ed6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Fri, 29 Nov 2024 23:30:33 +0100 Subject: [PATCH 04/13] Enable Catalogs in Admin --- ram/bookshelf/admin.py | 59 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/ram/bookshelf/admin.py b/ram/bookshelf/admin.py index 58de299..011b6e0 100644 --- a/ram/bookshelf/admin.py +++ b/ram/bookshelf/admin.py @@ -2,7 +2,7 @@ from adminsortable2.admin import SortableAdminBase, SortableInlineAdminMixin from bookshelf.models import ( - BaseBookProperty, BaseBookImage, Book, Author, Publisher + BaseBookProperty, BaseBookImage, Book, Author, Publisher, Catalog ) @@ -12,6 +12,7 @@ class BookImageInline(SortableInlineAdminMixin, admin.TabularInline): extra = 0 readonly_fields = ("image_thumbnail",) classes = ["collapse"] + verbose_name = "Image" class BookPropertyInline(admin.TabularInline): @@ -19,6 +20,8 @@ class BookPropertyInline(admin.TabularInline): min_num = 0 extra = 0 autocomplete_fields = ("property",) + verbose_name = "Property" + verbose_name_plural = "Properties" @admin.register(Book) @@ -26,11 +29,11 @@ class BookAdmin(SortableAdminBase, admin.ModelAdmin): inlines = (BookImageInline, BookPropertyInline,) list_display = ( "title", - "published", "get_authors", "get_publisher", "publication_year", - "number_of_pages" + "number_of_pages", + "published", ) readonly_fields = ("creation_time", "updated_time") search_fields = ("title", "publisher__name", "authors__last_name") @@ -87,3 +90,53 @@ class AuthorAdmin(admin.ModelAdmin): class PublisherAdmin(admin.ModelAdmin): list_display = ("name", "country") search_fields = ("name",) + + +@admin.register(Catalog) +class CatalogAdmin(SortableAdminBase, admin.ModelAdmin): + inlines = (BookImageInline, BookPropertyInline,) + list_display = ( + "manufacturer", + "years", + "get_scales", + "published", + ) + readonly_fields = ("creation_time", "updated_time") + search_fields = ("manufacturer__name", "years", "scales__scale") + list_filter = ("manufacturer__name", "publication_year", "scales__scale") + + fieldsets = ( + ( + None, + { + "fields": ( + "published", + "manufacturer", + "years", + "scales", + "ISBN", + "language", + "number_of_pages", + "publication_year", + "description", + "purchase_date", + "notes", + "tags", + ) + }, + ), + ( + "Audit", + { + "classes": ("collapse",), + "fields": ( + "creation_time", + "updated_time", + ), + }, + ), + ) + + @admin.display(description="Scales") + def get_scales(self, obj): + return ", ".join(s.scale for s in obj.scales.all()) From 83444266cbcdcc5a209f632c04654913f21a1491 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Fri, 29 Nov 2024 23:43:36 +0100 Subject: [PATCH 05/13] Add Catalogs views, but still need to fix templates (use books for now) --- ram/bookshelf/admin.py | 2 +- ram/bookshelf/models.py | 9 ++++-- .../templates/bookshelf/bookshelf_menu.html | 1 + ram/portal/templatetags/show_menu.py | 6 ++-- ram/portal/urls.py | 17 +++++++++++ ram/portal/views.py | 30 ++++++++++++++++++- 6 files changed, 58 insertions(+), 7 deletions(-) diff --git a/ram/bookshelf/admin.py b/ram/bookshelf/admin.py index 011b6e0..5c297b8 100644 --- a/ram/bookshelf/admin.py +++ b/ram/bookshelf/admin.py @@ -139,4 +139,4 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin): @admin.display(description="Scales") def get_scales(self, obj): - return ", ".join(s.scale for s in obj.scales.all()) + return "/".join(s.scale for s in obj.scales.all()) diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index af0643e..83c32c9 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -54,9 +54,6 @@ class BaseBook(BaseModel): Tag, related_name="bookshelf", blank=True ) - def get_absolute_url(self): - return reverse("book", kwargs={"uuid": self.uuid}) - def delete(self, *args, **kwargs): shutil.rmtree( os.path.join( @@ -110,6 +107,9 @@ def __str__(self): def publisher_name(self): return self.publisher.name + def get_absolute_url(self): + return reverse("book", kwargs={"uuid": self.uuid}) + class Catalog(BaseBook): manufacturer = models.ForeignKey( @@ -127,3 +127,6 @@ class Meta: def __str__(self): scales = "/".join([s.scale for s in self.scales.all()]) return "%s %s %s" % (self.manufacturer.name, self.years, scales) + + def get_absolute_url(self): + return reverse("catalog", kwargs={"uuid": self.uuid}) diff --git a/ram/portal/templates/bookshelf/bookshelf_menu.html b/ram/portal/templates/bookshelf/bookshelf_menu.html index 2c6ab5f..52ce111 100644 --- a/ram/portal/templates/bookshelf/bookshelf_menu.html +++ b/ram/portal/templates/bookshelf/bookshelf_menu.html @@ -5,6 +5,7 @@ {% endif %} diff --git a/ram/portal/templatetags/show_menu.py b/ram/portal/templatetags/show_menu.py index 44cf520..951a7ba 100644 --- a/ram/portal/templatetags/show_menu.py +++ b/ram/portal/templatetags/show_menu.py @@ -1,13 +1,15 @@ from django import template from portal.models import Flatpage -from bookshelf.models import Book +from bookshelf.models import Book, Catalog register = template.Library() @register.inclusion_tag('bookshelf/bookshelf_menu.html') def show_bookshelf_menu(): - return {"bookshelf_menu": Book.objects.exists()} + return { + "bookshelf_menu": (Book.objects.exists() or Catalog.objects.exists()) + } @register.inclusion_tag('flatpages/flatpages_menu.html') diff --git a/ram/portal/urls.py b/ram/portal/urls.py index 0b27cf4..be996c1 100644 --- a/ram/portal/urls.py +++ b/ram/portal/urls.py @@ -15,6 +15,8 @@ Types, Books, GetBook, + Catalogs, + GetCatalog, SearchObjects, ) @@ -98,6 +100,21 @@ name="books_pagination" ), path("bookshelf/book/", GetBook.as_view(), name="book"), + path( + "bookshelf/catalogs", + Catalogs.as_view(template="bookshelf/books.html"), + name="catalogs" + ), + path( + "bookshelf/catalogs/page/", + Catalogs.as_view(template="bookshelf/books.html"), + name="catalogs_pagination" + ), + path( + "bookshelf/catalog/", + GetCatalog.as_view(), + name="catalog" + ), path( "search", SearchObjects.as_view(http_method_names=["post"]), diff --git a/ram/portal/views.py b/ram/portal/views.py index fbe4ca1..5edca3d 100644 --- a/ram/portal/views.py +++ b/ram/portal/views.py @@ -15,7 +15,7 @@ from portal.models import Flatpage from roster.models import RollingStock from consist.models import Consist -from bookshelf.models import Book +from bookshelf.models import Book, Catalog from metadata.models import ( Company, Manufacturer, @@ -536,6 +536,34 @@ def get(self, request, uuid): ) +class Catalogs(GetData): + title = "Catalogs" + item_type = "book" + + def get_data(self, request): + return Catalog.objects.get_published(request.user).all() + + +class GetCatalog(View): + def get(self, request, uuid): + try: + catalog = Catalog.objects.get_published(request.user).get(uuid=uuid) + except ObjectDoesNotExist: + raise Http404 + + catalog_properties = catalog.property.get_public(request.user) + return render( + request, + "bookshelf/book.html", + { + "title": catalog, + "catalog_properties": catalog_properties, + "book": catalog, + }, + ) + + + class GetFlatpage(View): def get(self, request, flatpage): try: From 005ea110112e4360c55fe0983fbec5f4923e06eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Fri, 29 Nov 2024 23:49:35 +0100 Subject: [PATCH 06/13] Minor improvements --- ram/portal/templates/bookshelf/bookshelf_menu.html | 4 ++++ ram/portal/templatetags/show_menu.py | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/ram/portal/templates/bookshelf/bookshelf_menu.html b/ram/portal/templates/bookshelf/bookshelf_menu.html index 52ce111..7321045 100644 --- a/ram/portal/templates/bookshelf/bookshelf_menu.html +++ b/ram/portal/templates/bookshelf/bookshelf_menu.html @@ -4,8 +4,12 @@ Bookshelf {% endif %} diff --git a/ram/portal/templatetags/show_menu.py b/ram/portal/templatetags/show_menu.py index 951a7ba..35421dd 100644 --- a/ram/portal/templatetags/show_menu.py +++ b/ram/portal/templatetags/show_menu.py @@ -7,8 +7,11 @@ @register.inclusion_tag('bookshelf/bookshelf_menu.html') def show_bookshelf_menu(): + # FIXME: Filter out unpublished books and catalogs? return { - "bookshelf_menu": (Book.objects.exists() or Catalog.objects.exists()) + "bookshelf_menu": (Book.objects.exists() or Catalog.objects.exists()), + "books_menu": Book.objects.exists(), + "catalogs_menu": Catalog.objects.exists(), } From cbf6c942b9b81d6c22e861b084401fd4bcb49a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniele=20Vigan=C3=B2?= Date: Sun, 22 Dec 2024 18:53:47 +0100 Subject: [PATCH 07/13] Complete Catalogs with code refactoring --- ram/bookshelf/admin.py | 2 + .../0016_basebook_book_catalogue.py | 2 - ram/bookshelf/models.py | 18 ++++-- ram/portal/templates/bookshelf/book.html | 29 +++++++-- ram/portal/templates/bookshelf/books.html | 8 ++- ram/portal/templates/cards.html | 2 +- ram/portal/templates/cards/book.html | 18 +++++- ram/portal/templatetags/dynamic_url.py | 19 ++++++ ram/portal/urls.py | 14 ++--- ram/portal/views.py | 59 +++++++++---------- 10 files changed, 115 insertions(+), 56 deletions(-) create mode 100644 ram/portal/templatetags/dynamic_url.py diff --git a/ram/bookshelf/admin.py b/ram/bookshelf/admin.py index 5c297b8..f2d7e70 100644 --- a/ram/bookshelf/admin.py +++ b/ram/bookshelf/admin.py @@ -35,6 +35,7 @@ class BookAdmin(SortableAdminBase, admin.ModelAdmin): "number_of_pages", "published", ) + autocomplete_fields = ("authors", "publisher") readonly_fields = ("creation_time", "updated_time") search_fields = ("title", "publisher__name", "authors__last_name") list_filter = ("publisher__name", "authors") @@ -101,6 +102,7 @@ class CatalogAdmin(SortableAdminBase, admin.ModelAdmin): "get_scales", "published", ) + autocomplete_fields = ("manufacturer",) readonly_fields = ("creation_time", "updated_time") search_fields = ("manufacturer__name", "years", "scales__scale") list_filter = ("manufacturer__name", "publication_year", "scales__scale") diff --git a/ram/bookshelf/migrations/0016_basebook_book_catalogue.py b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py index 0be21a2..5e44540 100644 --- a/ram/bookshelf/migrations/0016_basebook_book_catalogue.py +++ b/ram/bookshelf/migrations/0016_basebook_book_catalogue.py @@ -127,8 +127,6 @@ class Migration(migrations.Migration): ( "manufacturer", models.ForeignKey( - blank=True, - null=True, on_delete=django.db.models.deletion.CASCADE, to="metadata.manufacturer", ), diff --git a/ram/bookshelf/models.py b/ram/bookshelf/models.py index 83c32c9..a632bdf 100644 --- a/ram/bookshelf/models.py +++ b/ram/bookshelf/models.py @@ -108,15 +108,16 @@ def publisher_name(self): return self.publisher.name def get_absolute_url(self): - return reverse("book", kwargs={"uuid": self.uuid}) + return reverse( + "bookshelf_item", + kwargs={"selector": "book", "uuid": self.uuid} + ) class Catalog(BaseBook): manufacturer = models.ForeignKey( Manufacturer, on_delete=models.CASCADE, - null=True, - blank=True, ) years = models.CharField(max_length=12) scales = models.ManyToManyField(Scale) @@ -125,8 +126,15 @@ class Meta: ordering = ["manufacturer", "publication_year"] def __str__(self): - scales = "/".join([s.scale for s in self.scales.all()]) + scales = self.get_scales return "%s %s %s" % (self.manufacturer.name, self.years, scales) def get_absolute_url(self): - return reverse("catalog", kwargs={"uuid": self.uuid}) + return reverse( + "bookshelf_item", + kwargs={"selector": "catalog", "uuid": self.uuid} + ) + + @property + def get_scales(self): + return "/".join([s.scale for s in self.scales.all()]) diff --git a/ram/portal/templates/bookshelf/book.html b/ram/portal/templates/bookshelf/book.html index 23f73fd..4d4fc43 100644 --- a/ram/portal/templates/bookshelf/book.html +++ b/ram/portal/templates/bookshelf/book.html @@ -1,4 +1,5 @@ {% extends 'base.html' %} +{% load dynamic_url %} {% block header %} {% if book.tags.all %} @@ -57,24 +58,39 @@ {{ book.description | safe }} + {% if type == "catalog" %} + Catalog + {% elif type == "book" %} Book + {% endif %} + {% if type == "catalog" %} + + Manufacturer + {{ book.manufacturer }} + + + Scales + {{ book.get_scales }} + + {% elif type == "book" %} Title {{ book.title }} - Authors - -
    {% for a in book.authors.all %}
  • {{ a }}
  • {% endfor %}
- + Authors + +
    {% for a in book.authors.all %}
  • {{ a }}
  • {% endfor %}
+ - Publisher + Publisher {{ book.publisher }} + {% endif %} ISBN {{ book.ISBN|default:"-" }} @@ -120,7 +136,8 @@
- {% if request.user.is_staff %}Edit{% endif %} + FIXME: {{ type }} + {% if request.user.is_staff %}Edit{% endif %}
diff --git a/ram/portal/templates/bookshelf/books.html b/ram/portal/templates/bookshelf/books.html index 049c7b0..a2e3e2e 100644 --- a/ram/portal/templates/bookshelf/books.html +++ b/ram/portal/templates/bookshelf/books.html @@ -1,11 +1,13 @@ {% extends "cards.html" %} +{% load dynamic_url %} + {% block pagination %} {% if data.has_other_pages %}