From 2caa6415139fe58938a62dca695639ba0cc86dda Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Wed, 15 Apr 2020 18:00:55 +0200 Subject: [PATCH] Collections in catalogue. --- src/catalogue/admin.py | 48 +++++++++++++++++-- .../commands/import_catalogue_from_wl_dump.py | 25 +++++----- src/catalogue/migrations/0012_collection.py | 23 +++++++++ .../migrations/0013_auto_20200415_1755.py | 39 +++++++++++++++ src/catalogue/models.py | 31 +++++++++++- src/catalogue/wikidata.py | 8 ++++ 6 files changed, 156 insertions(+), 18 deletions(-) create mode 100644 src/catalogue/migrations/0012_collection.py create mode 100644 src/catalogue/migrations/0013_auto_20200415_1755.py diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py index bd783b99..95da4994 100644 --- a/src/catalogue/admin.py +++ b/src/catalogue/admin.py @@ -4,18 +4,60 @@ from .wikidata import WikidataAdminMixin class AuthorAdmin(WikidataAdminMixin, admin.ModelAdmin): - list_display = "first_name", "last_name", "notes" + list_display = ["first_name", "last_name", 'status', "year_of_death", "priority", "wikidata_link"] + list_filter = ['year_of_death', 'priority', 'collections', 'status'] search_fields = ["first_name", "last_name", "wikidata"] prepopulated_fields = {"slug": ("first_name", "last_name")} + autocomplete_fields = ['collections'] admin.site.register(models.Author, AuthorAdmin) class BookAdmin(WikidataAdminMixin, admin.ModelAdmin): - list_display = "title", "notes" - autocomplete_fields = ["authors", "translators"] + list_display = ["title", 'authors_str', 'translators_str', 'language', 'pd_year', 'priority', 'wikidata_link'] + search_fields = ["title", 'wikidata'] + autocomplete_fields = ["authors", "translators", "based_on", 'collections'] prepopulated_fields = {"slug": ("title",)} + list_filter = ['language', 'pd_year', 'collections'] + readonly_fields = ['wikidata_link'] + fieldsets = [ + (None, {'fields': [ + ('wikidata', 'wikidata_link'), + ]}), + ('Identification', {'fields': [ + 'title', 'slug', 'authors', 'translators', 'language', + 'based_on', + 'pd_year', + ]}), + ('Plan', {'fields': [ + 'scans_source', + 'text_source', + 'priority', + 'collections', + 'notes', + ]}), + ] admin.site.register(models.Book, BookAdmin) + + +class AuthorInline(admin.TabularInline): + model = models.Author.collections.through + autocomplete_fields = ['author'] + + +class BookInline(admin.TabularInline): + model = models.Book.collections.through + autocomplete_fields = ['book'] + + +class CollectionAdmin(admin.ModelAdmin): + list_display = ['name'] + autocomplete_fields = [] + prepopulated_fields = {'slug': ('name',)} + search_fields = ['name'] + inlines = [AuthorInline, BookInline] + +admin.site.register(models.Collection, CollectionAdmin) diff --git a/src/catalogue/management/commands/import_catalogue_from_wl_dump.py b/src/catalogue/management/commands/import_catalogue_from_wl_dump.py index 4d69eb4d..ea3f8054 100644 --- a/src/catalogue/management/commands/import_catalogue_from_wl_dump.py +++ b/src/catalogue/management/commands/import_catalogue_from_wl_dump.py @@ -6,6 +6,15 @@ import wikidata from catalogue.models import Book, Author +def parse_name(name): + name_pieces = name.rsplit(' ', 1) + if len(name_pieces) == 1: + return name_pieces[0], '' + else: + return name_pieces + + + class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('path') @@ -28,16 +37,9 @@ class Command(BaseCommand): book.save() if not book.authors.exists(): - author_name = item['fields']['author'] - name_pieces = author_name.rsplit(' ', 1) - if len(name_pieces) == 1: - first_name, last_name = name_pieces, '' - else: - first_name, last_name = name_pieces - + first_name, last_name = parse_name(item['fields']['author']) author, created = Author.objects.get_or_create(first_name=first_name, last_name=last_name) if not author.slug: - print(author.slug, author_name) author.slug = slugify(author_name) author.save() book.authors.set([author]) @@ -45,12 +47,7 @@ class Command(BaseCommand): slug = item['fields']['slug'] author, created = Author.objects.get_or_create(slug=slug) if not author.first_name and not author.last_name: - author_name = item['fields']['name'] - name_pieces = author_name.rsplit(' ', 1) - if len(name_pieces) == 1: - author.first_name, author.last_name = name_pieces, '' - else: - author.first_name, author.last_name = name_pieces + author.first_name, author.last_name = parse_name(item['fields']['name']) author.year_of_death = author.year_of_death or item['fields']['death'] author.notes = author.notes or item['fields']['description'] author.gazeta_link = author.gazeta_link or item['fields']['gazeta_link'] diff --git a/src/catalogue/migrations/0012_collection.py b/src/catalogue/migrations/0012_collection.py new file mode 100644 index 00000000..3e5409e5 --- /dev/null +++ b/src/catalogue/migrations/0012_collection.py @@ -0,0 +1,23 @@ +# Generated by Django 3.0.4 on 2020-04-15 17:15 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0011_auto_20200415_1517'), + ] + + operations = [ + migrations.CreateModel( + name='Collection', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('slug', models.SlugField(max_length=255, unique=True)), + ('authors', models.ManyToManyField(blank=True, to='catalogue.Author')), + ('books', models.ManyToManyField(blank=True, to='catalogue.Book')), + ], + ), + ] diff --git a/src/catalogue/migrations/0013_auto_20200415_1755.py b/src/catalogue/migrations/0013_auto_20200415_1755.py new file mode 100644 index 00000000..3de73880 --- /dev/null +++ b/src/catalogue/migrations/0013_auto_20200415_1755.py @@ -0,0 +1,39 @@ +# Generated by Django 3.0.4 on 2020-04-15 17:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0012_collection'), + ] + + operations = [ + migrations.AlterModelOptions( + name='author', + options={'ordering': ('last_name', 'first_name', 'year_of_death')}, + ), + migrations.AlterModelOptions( + name='book', + options={'ordering': ('title',)}, + ), + migrations.RemoveField( + model_name='collection', + name='authors', + ), + migrations.RemoveField( + model_name='collection', + name='books', + ), + migrations.AddField( + model_name='author', + name='collections', + field=models.ManyToManyField(blank=True, to='catalogue.Collection'), + ), + migrations.AddField( + model_name='book', + name='collections', + field=models.ManyToManyField(blank=True, to='catalogue.Collection'), + ), + ] diff --git a/src/catalogue/models.py b/src/catalogue/models.py index 250a115e..e41ba35e 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -26,6 +26,10 @@ class Author(WikidataMixin, models.Model): priority = models.PositiveSmallIntegerField( default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))] ) + collections = models.ManyToManyField('Collection', blank=True) + + class Meta: + ordering = ('last_name', 'first_name', 'year_of_death') class Wikidata: first_name = WIKIDATA.GIVEN_NAME @@ -58,6 +62,10 @@ class Book(WikidataMixin, models.Model): default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))] ) pd_year = models.IntegerField(null=True, blank=True) + collections = models.ManyToManyField('Collection', blank=True) + + class Meta: + ordering = ('title',) class Wikidata: authors = WIKIDATA.AUTHOR @@ -68,4 +76,25 @@ class Book(WikidataMixin, models.Model): notes = "description" def __str__(self): - return self.title + txt = self.title + astr = self.authors_str() + if astr: + txt = f'{astr} – {txt}' + tstr = self.translators_str() + if tstr: + txt = f'{txt} (tłum. {tstr})' + return txt + + def authors_str(self): + return ', '.join(str(author) for author in self.authors.all()) + + def translators_str(self): + return ', '.join(str(author) for author in self.translators.all()) + + +class Collection(models.Model): + name = models.CharField(max_length=255) + slug = models.SlugField(max_length=255, unique=True) + + def __str__(self): + return self.name diff --git a/src/catalogue/wikidata.py b/src/catalogue/wikidata.py index 4e63c095..c6885705 100644 --- a/src/catalogue/wikidata.py +++ b/src/catalogue/wikidata.py @@ -1,6 +1,7 @@ from datetime import date from django.db import models from django.db.models.signals import m2m_changed +from django.utils.html import format_html from django.utils.translation import gettext_lazy as _ from django.dispatch import receiver from wikidata.client import Client @@ -85,3 +86,10 @@ class WikidataAdminMixin: def save_related(self, request, form, formsets, change): super().save_related(request, form, formsets, change) form.instance.save() + + def wikidata_link(self, obj): + if obj.wikidata: + return format_html('{wd}', wd=obj.wikidata) + else: + return '' + wikidata_link.admin_order_field = 'wikidata' -- 2.20.1