From ff96835c2a4eb47f2270a84cf2fe965b7b9cb9ad Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 4 Nov 2020 10:35:13 -0800 Subject: [PATCH] Migrate default edition field to work model Fixes #281 --- bookwyrm/connectors/abstract_connector.py | 3 +- bookwyrm/connectors/openlibrary.py | 1 - bookwyrm/connectors/self_connector.py | 6 +++- .../migrations/0008_work_default_edition.py | 35 +++++++++++++++++++ bookwyrm/models/book.py | 13 +------ 5 files changed, 43 insertions(+), 15 deletions(-) create mode 100644 bookwyrm/migrations/0008_work_default_edition.py diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 1faa9bf9..215d0510 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -128,9 +128,10 @@ class AbstractConnector(ABC): if not edition: ed_key = self.get_remote_id_from_data(edition_data) edition = self.create_book(ed_key, edition_data, models.Edition) - edition.default = True edition.parent_work = work edition.save() + work.default_edition = edition + work.save() # now's our change to fill in author gaps if not edition.authors and work.authors: diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index 00b76f41..9b8afaa6 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -72,7 +72,6 @@ class Connector(AbstractConnector): ] - def get_remote_id_from_data(self, data): try: key = data['key'] diff --git a/bookwyrm/connectors/self_connector.py b/bookwyrm/connectors/self_connector.py index fb70978d..2df07c19 100644 --- a/bookwyrm/connectors/self_connector.py +++ b/bookwyrm/connectors/self_connector.py @@ -1,5 +1,6 @@ ''' using a bookwyrm instance as a source of book data ''' from django.contrib.postgres.search import SearchRank, SearchVector +from django.db.models import F from bookwyrm import models from .abstract_connector import AbstractConnector, SearchResult @@ -30,7 +31,10 @@ class Connector(AbstractConnector): ).filter( rank__gt=min_confidence ).order_by('-rank') - results = results.filter(default=True) or results + + # remove non-default editions, if possible + results = results.filter(parent_work__default_edition__id=F('id')) \ + or results search_results = [] for book in results[:10]: diff --git a/bookwyrm/migrations/0008_work_default_edition.py b/bookwyrm/migrations/0008_work_default_edition.py new file mode 100644 index 00000000..da1f959e --- /dev/null +++ b/bookwyrm/migrations/0008_work_default_edition.py @@ -0,0 +1,35 @@ +# Generated by Django 3.0.7 on 2020-11-04 18:15 + +from django.db import migrations, models +import django.db.models.deletion + + +def set_default_edition(app_registry, schema_editor): + db_alias = schema_editor.connection.alias + works = app_registry.get_model('bookwyrm', 'Work').objects.using(db_alias) + editions = app_registry.get_model('bookwyrm', 'Edition').objects.using(db_alias) + for work in works: + ed = editions.filter(parent_work=work, default=True).first() + if not ed: + ed = editions.filter(parent_work=work).first() + work.default_edition = ed + work.save() + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0007_auto_20201103_0014'), + ] + + operations = [ + migrations.AddField( + model_name='work', + name='default_edition', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='bookwyrm.Edition'), + ), + migrations.RunPython(set_default_edition), + migrations.RemoveField( + model_name='edition', + name='default', + ), + ] diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index 93d9393d..0067d33e 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -139,29 +139,18 @@ class Work(Book): ''' a work (an abstract concept of a book that manifests in an edition) ''' # library of congress catalog control number lccn = models.CharField(max_length=255, blank=True, null=True) + default_edition = models.ForeignKey('Edition', on_delete=models.PROTECT, null=True) @property def editions_path(self): ''' it'd be nice to serialize the edition instead but, recursion ''' return [e.remote_id for e in self.edition_set.all()] - - @property - def default_edition(self): - ''' best-guess attempt at picking the default edition for this work ''' - ed = Edition.objects.filter(parent_work=self, default=True).first() - if not ed: - ed = Edition.objects.filter(parent_work=self).first() - return ed - activity_serializer = activitypub.Work class Edition(Book): ''' an edition of a book ''' - # default -> this is what gets displayed for a work - default = models.BooleanField(default=False) - # these identifiers only apply to editions, not works isbn_10 = models.CharField(max_length=255, blank=True, null=True) isbn_13 = models.CharField(max_length=255, blank=True, null=True)