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] 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 tinymce import models as tinymce 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 @@ class Author(models.Model): 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 @@ class Book(BaseModel): ), 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)