From 21cd47e315b2e86edeff93bac5d1eca5b5d2c428 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Mon, 2 Nov 2020 13:47:58 +0100 Subject: [PATCH] Use unmanaged keys instead of some magic. --- src/catalogue/models.py | 7 --- .../templates/catalogue/author_detail.html | 4 +- .../templates/catalogue/book_detail.html | 2 +- .../templates/catalogue/catalogue.html | 4 +- src/catalogue/utils.py | 49 ------------------- src/catalogue/views.py | 16 ++---- src/documents/ebook_utils.py | 2 +- .../management/commands/add_parent.py | 2 +- .../management/commands/insert_isbn.py | 2 +- .../migrations/0003_auto_20201102_1324.py | 20 ++++++++ .../migrations/0004_auto_20201102_1325.py | 18 +++++++ .../migrations/0005_auto_20201102_1340.py | 20 ++++++++ src/documents/models/book.py | 24 +++++---- src/documents/views.py | 2 +- 14 files changed, 85 insertions(+), 87 deletions(-) delete mode 100644 src/catalogue/utils.py create mode 100644 src/documents/migrations/0003_auto_20201102_1324.py create mode 100644 src/documents/migrations/0004_auto_20201102_1325.py create mode 100644 src/documents/migrations/0005_auto_20201102_1340.py diff --git a/src/catalogue/models.py b/src/catalogue/models.py index cd64f843..18978467 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -6,7 +6,6 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from wikidata.client import Client from .constants import WIKIDATA -from .utils import UnrelatedManager from .wikidata import WikidataMixin @@ -136,8 +135,6 @@ class Book(WikidataMixin, models.Model): estimated_verses = models.IntegerField(_("estimated number of verses"), null=True, blank=True) estimate_source = models.CharField(_("source of estimates"), max_length=2048, blank=True) - objects = UnrelatedManager() - class Meta: ordering = ("title",) verbose_name = _('book') @@ -170,10 +167,6 @@ class Book(WikidataMixin, models.Model): def translators_str(self): return ", ".join(str(author) for author in self.translators.all()) - def get_document_books(self): - DBook = apps.get_model("documents", "Book") - return DBook.objects.filter(dc_slug=self.slug) - def get_estimated_costs(self): return { work_type: work_type.calculate(self) diff --git a/src/catalogue/templates/catalogue/author_detail.html b/src/catalogue/templates/catalogue/author_detail.html index 177f3be9..9ee44c3e 100644 --- a/src/catalogue/templates/catalogue/author_detail.html +++ b/src/catalogue/templates/catalogue/author_detail.html @@ -49,7 +49,7 @@ {{ book.get_priorty_display }} - {% for b in book.document_books %} + {% for b in book.document_books.all %} {{ b }} @@ -75,7 +75,7 @@ {{ book.get_priorty_display }} - {% for b in book.document_books %} + {% for b in book.document_books.all %} {{ b }} diff --git a/src/catalogue/templates/catalogue/book_detail.html b/src/catalogue/templates/catalogue/book_detail.html index 2c59c359..85cfcc96 100644 --- a/src/catalogue/templates/catalogue/book_detail.html +++ b/src/catalogue/templates/catalogue/book_detail.html @@ -67,7 +67,7 @@ {{ book.get_priorty_display }} - {% for b in book.get_document_books %} + {% for b in book.document_books.all %} {{ b }} diff --git a/src/catalogue/templates/catalogue/catalogue.html b/src/catalogue/templates/catalogue/catalogue.html index 715ba8f1..dca509e6 100644 --- a/src/catalogue/templates/catalogue/catalogue.html +++ b/src/catalogue/templates/catalogue/catalogue.html @@ -50,7 +50,7 @@ {{ book.get_priorty_display }} - {% for b in book.document_books %} + {% for b in book.document_books.all %} {{ b }} @@ -76,7 +76,7 @@ {{ book.get_priorty_display }} - {% for b in book.document_books %} + {% for b in book.document_books.all %} {{ b }} diff --git a/src/catalogue/utils.py b/src/catalogue/utils.py deleted file mode 100644 index 00f71878..00000000 --- a/src/catalogue/utils.py +++ /dev/null @@ -1,49 +0,0 @@ -# This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later. -# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. -# -from collections import defaultdict -from django.db.models import QuerySet -from django.db.models.manager import BaseManager - - -class UnrelatedQuerySet(QuerySet): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self._prefetch_unrelated_lookups = {} - self._prefetch_unrelated_done = False - - def _clone(self): - c = super()._clone() - c._prefetch_unrelated_lookups = self._prefetch_unrelated_lookups.copy() - return c - - def prefetch_unrelated(self, attribute, field, other_model, other_field): - clone = self._clone() - clone._prefetch_unrelated_lookups[field] = (attribute, other_model, other_field) - return clone - - def _fetch_all(self): - prefetch_done = self._prefetch_done - super()._fetch_all() - if self._prefetch_unrelated_lookups and not prefetch_done: - self._prefetch_unrelated_objects() - - def _prefetch_unrelated_objects(self): - for ( - field, - (attribute, other_model, other_field), - ) in self._prefetch_unrelated_lookups.items(): - values = set([getattr(obj, field) for obj in self._result_cache]) - other_objects = other_model._default_manager.filter( - **{f"{other_field}__in": values} - ) - results = defaultdict(list) - for other_obj in other_objects: - results[getattr(other_obj, other_field)].append(other_obj) - for obj in self._result_cache: - setattr(obj, attribute, results.get(getattr(obj, field))) - self._prefetch_unrelated_done = True - - -class UnrelatedManager(BaseManager.from_queryset(UnrelatedQuerySet)): - pass diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 0b29b6f4..792ea700 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -12,13 +12,8 @@ class CatalogueView(TemplateView): def get_context_data(self): ctx = super().get_context_data() - documents_books_queryset = models.Book.objects.prefetch_unrelated( - "document_books", "slug", documents.models.Book, "dc_slug" - ) - ctx["authors"] = models.Author.objects.all().prefetch_related( - Prefetch("book_set", queryset=documents_books_queryset), - Prefetch("translated_book_set", queryset=documents_books_queryset), - ) + ctx["authors"] = models.Author.objects.all().prefetch_related('book_set__book_set', 'translated_book_set__book_set') + return ctx @@ -28,12 +23,9 @@ class AuthorView(TemplateView): def get_context_data(self, slug): ctx = super().get_context_data() - documents_books_queryset = models.Book.objects.prefetch_unrelated( - "document_books", "slug", documents.models.Book, "dc_slug" - ) authors = models.Author.objects.filter(slug=slug).prefetch_related( - Prefetch("book_set", queryset=documents_books_queryset), - Prefetch("translated_book_set", queryset=documents_books_queryset), + Prefetch("book_set"), + Prefetch("translated_book_set"), ) ctx["author"] = authors.first() return ctx diff --git a/src/documents/ebook_utils.py b/src/documents/ebook_utils.py index e75ed777..9253d59f 100644 --- a/src/documents/ebook_utils.py +++ b/src/documents/ebook_utils.py @@ -14,7 +14,7 @@ class RedakcjaDocProvider(DocProvider): self.publishable = publishable def by_slug(self, slug): - return BytesIO(Book.objects.get(dc_slug=slug + return BytesIO(Book.objects.get(catalogue_book_id=slug ).materialize(publishable=self.publishable ).encode('utf-8')) diff --git a/src/documents/management/commands/add_parent.py b/src/documents/management/commands/add_parent.py index 59767bf6..4bd242db 100644 --- a/src/documents/management/commands/add_parent.py +++ b/src/documents/management/commands/add_parent.py @@ -71,7 +71,7 @@ class Command(BaseCommand): def handle(self, slug, **options): children_slugs = [line.strip() for line in sys.stdin] - children = Book.objects.filter(dc_slug__in=children_slugs) + children = Book.objects.filter(catalogue_book_id__in=children_slugs) desc_elements = [dc_desc_element(child) for child in children] title = u'Utwory wybrane' own_attributes = { diff --git a/src/documents/management/commands/insert_isbn.py b/src/documents/management/commands/insert_isbn.py index 536d30ff..15104d71 100644 --- a/src/documents/management/commands/insert_isbn.py +++ b/src/documents/management/commands/insert_isbn.py @@ -62,7 +62,7 @@ class Command(BaseCommand): for slug, isbn_list in isbn_lists.iteritems(): print('processing %s' % slug) - book = Book.objects.get(dc_slug=slug) + book = Book.objects.get(catalogue_book_id=slug) chunk = book.chunk_set.first() old_head = chunk.head src = old_head.materialize() diff --git a/src/documents/migrations/0003_auto_20201102_1324.py b/src/documents/migrations/0003_auto_20201102_1324.py new file mode 100644 index 00000000..79c30738 --- /dev/null +++ b/src/documents/migrations/0003_auto_20201102_1324.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.4 on 2020-11-02 13:24 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0029_auto_20201102_1315'), + ('documents', '0002_auto_20200322_2131'), + ] + + operations = [ + migrations.AlterField( + model_name='book', + name='dc_slug', + field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='catalogue.Book', to_field='slug'), + ), + ] diff --git a/src/documents/migrations/0004_auto_20201102_1325.py b/src/documents/migrations/0004_auto_20201102_1325.py new file mode 100644 index 00000000..2a4eef1e --- /dev/null +++ b/src/documents/migrations/0004_auto_20201102_1325.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.4 on 2020-11-02 13:25 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('documents', '0003_auto_20201102_1324'), + ] + + operations = [ + migrations.RenameField( + model_name='book', + old_name='dc_slug', + new_name='catalogue_book', + ), + ] diff --git a/src/documents/migrations/0005_auto_20201102_1340.py b/src/documents/migrations/0005_auto_20201102_1340.py new file mode 100644 index 00000000..0731fa83 --- /dev/null +++ b/src/documents/migrations/0005_auto_20201102_1340.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.4 on 2020-11-02 13:40 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0029_auto_20201102_1315'), + ('documents', '0004_auto_20201102_1325'), + ] + + operations = [ + migrations.AlterField( + model_name='book', + name='catalogue_book', + field=models.ForeignKey(blank=True, editable=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='document_books', related_query_name='document_book', to='catalogue.Book', to_field='slug'), + ), + ] diff --git a/src/documents/models/book.py b/src/documents/models/book.py index 24d0cea0..e16de686 100644 --- a/src/documents/models/book.py +++ b/src/documents/models/book.py @@ -30,7 +30,6 @@ class Book(models.Model): gallery = models.CharField(_('scan gallery name'), max_length=255, blank=True) project = models.ForeignKey(Project, models.SET_NULL, null=True, blank=True) - #wl_slug = models.CharField(_('title'), max_length=255, null=True, db_index=True, editable=False) parent = models.ForeignKey('self', models.SET_NULL, null=True, blank=True, verbose_name=_('parent'), related_name="children", editable=False) parent_number = models.IntegerField(_('parent number'), null=True, blank=True, db_index=True, editable=False) @@ -41,8 +40,15 @@ class Book(models.Model): _on_track = models.IntegerField(null=True, blank=True, db_index=True, editable=False) dc_cover_image = models.ForeignKey(Image, blank=True, null=True, db_index=True, on_delete=models.SET_NULL, editable=False) - dc_slug = models.CharField(max_length=128, null=True, blank=True, - editable=False, db_index=True) + catalogue_book = models.ForeignKey( + 'catalogue.Book', + models.DO_NOTHING, + to_field='slug', + null=True, blank=True, + editable=False, db_index=True, + related_name='document_books', + related_query_name='document_book', + ) class NoTextError(BaseException): pass @@ -90,11 +96,6 @@ class Book(models.Model): def gallery_url(self): return '%s%s%s/' % (settings.MEDIA_URL, settings.IMAGE_DIR, self.gallery) - @property - def catalogue_book(self): - CBook = apps.get_model('catalogue', 'Book') - return CBook.objects.filter(slug=self.dc_slug).first() - # Creating & manipulating # ======================= @@ -343,13 +344,15 @@ class Book(models.Model): def refresh_dc_cache(self): update = { - 'dc_slug': None, + 'catalogue_book_id': None, 'dc_cover_image': None, } info = self.book_info() + print(info) if info is not None: - update['dc_slug'] = info.url.slug + update['catalogue_book_id'] = info.url.slug + print(info.url.slug) if info.cover_source: try: image = Image.objects.get(pk=int(info.cover_source.rstrip('/').rsplit('/', 1)[-1])) @@ -358,6 +361,7 @@ class Book(models.Model): else: if info.cover_source == image.get_full_url(): update['dc_cover_image'] = image + print(update) Book.objects.filter(pk=self.pk).update(**update) def touch(self): diff --git a/src/documents/views.py b/src/documents/views.py index 397d78bd..05f8853f 100644 --- a/src/documents/views.py +++ b/src/documents/views.py @@ -224,7 +224,7 @@ def book_xml(request, slug): @never_cache def book_xml_dc(request, slug): - book = get_object_or_404(Book, dc_slug=slug) + book = get_object_or_404(Book, catalogue_book_id=slug) return serve_xml(request, book, slug) -- 2.20.1