Collections in catalogue.
authorRadek Czajka <rczajka@rczajka.pl>
Wed, 15 Apr 2020 16:00:55 +0000 (18:00 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Wed, 15 Apr 2020 16:00:55 +0000 (18:00 +0200)
src/catalogue/admin.py
src/catalogue/management/commands/import_catalogue_from_wl_dump.py
src/catalogue/migrations/0012_collection.py [new file with mode: 0644]
src/catalogue/migrations/0013_auto_20200415_1755.py [new file with mode: 0644]
src/catalogue/models.py
src/catalogue/wikidata.py

index bd783b9..95da499 100644 (file)
@@ -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)
index 4d69eb4..ea3f805 100644 (file)
@@ -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 (file)
index 0000000..3e5409e
--- /dev/null
@@ -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 (file)
index 0000000..3de7388
--- /dev/null
@@ -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'),
+        ),
+    ]
index 250a115..e41ba35 100644 (file)
@@ -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
index 4e63c09..c688570 100644 (file)
@@ -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('<a href="https://www.wikidata.org/wiki/{wd}" target="_blank">{wd}</a>', wd=obj.wikidata)
+        else:
+            return ''
+    wikidata_link.admin_order_field = 'wikidata'