From 79d770e03bde9d600ec6effdcc9c15487ff23897 Mon Sep 17 00:00:00 2001 From: Jan Szejko Date: Wed, 6 Apr 2016 12:56:10 +0200 Subject: [PATCH 1/1] db optimizations --- src/api/management/commands/mobileinit.py | 2 +- src/catalogue/feeds.py | 3 +-- src/catalogue/models/book.py | 18 ++++++++++-------- .../templates/catalogue/book_mini_box.html | 4 ++-- src/catalogue/templatetags/catalogue_tags.py | 2 +- src/catalogue/tests/tags.py | 2 +- src/catalogue/views.py | 9 ++++++--- src/opds/views.py | 8 ++++---- src/picture/models.py | 17 +++++++++-------- .../templates/picture/picture_mini_box.html | 4 ++-- src/picture/views.py | 3 +-- src/wolnelektury/views.py | 4 ++-- 12 files changed, 40 insertions(+), 36 deletions(-) diff --git a/src/api/management/commands/mobileinit.py b/src/api/management/commands/mobileinit.py index b89fede9f..ccbff3e21 100755 --- a/src/api/management/commands/mobileinit.py +++ b/src/api/management/commands/mobileinit.py @@ -147,7 +147,7 @@ def add_book(db, book): parent_number = book.parent_number sort_key = book.sort_key size_str = pretty_size(html_file_size) - authors = ", ".join(t.name for t in book.tags.filter(category='author')) + authors = book.author_unicode() db.execute(book_sql, locals()) diff --git a/src/catalogue/feeds.py b/src/catalogue/feeds.py index 2a65c592b..0b7e4d474 100644 --- a/src/catalogue/feeds.py +++ b/src/catalogue/feeds.py @@ -52,8 +52,7 @@ class AudiobookFeed(Feed): return item.name def item_categories(self, item): - return sorted(set(author.name for author in - item.book.tags.filter(category='author').iterator())) + return sorted(item.book.authors().values_list('name', flat=True)) def item_description(self, item): lines = [] diff --git a/src/catalogue/models/book.py b/src/catalogue/models/book.py index a4017fbb9..f1501d02c 100644 --- a/src/catalogue/models/book.py +++ b/src/catalogue/models/book.py @@ -106,8 +106,11 @@ class Book(models.Model): except AttributeError: return '' - def author_str(self): - return ", ".join(str(t) for t in self.tags.filter(category='author')) + def authors(self): + return self.tags.filter(category='author') + + def author_unicode(self): + return ", ".join(self.authors().values_list('name', flat=True)) def save(self, force_insert=False, force_update=False, **kwargs): from sortify import sortify @@ -116,8 +119,8 @@ class Book(models.Model): self.title = unicode(self.title) # ??? try: - author = self.tags.filter(category='author')[0].sort_key - except IndexError: + author = self.authors().first().sort_key + except AttributeError: author = u'' self.sort_key_author = author @@ -474,7 +477,7 @@ class Book(models.Model): return books def pretty_title(self, html_links=False): - names = [(tag.name, tag.get_absolute_url()) for tag in self.tags.filter(category='author')] + names = [(tag.name, tag.get_absolute_url()) for tag in self.authors().only('name', 'category', 'slug')] books = self.parents() + [self] names.extend([(b.title, b.get_absolute_url()) for b in books]) @@ -504,8 +507,7 @@ class Book(models.Model): """ books_by_parent = {} - books = cls.objects.all().order_by('parent_number', 'sort_key').only( - 'title', 'parent', 'slug') + books = cls.objects.order_by('parent_number', 'sort_key').only('title', 'parent', 'slug') if book_filter: books = books.filter(book_filter).distinct() @@ -525,7 +527,7 @@ class Book(models.Model): books_by_author[tag] = [] for book in books_by_parent.get(None, ()): - authors = list(book.tags.filter(category='author')) + authors = list(book.authors().only('pk')) if authors: for author in authors: books_by_author[author].append(book) diff --git a/src/catalogue/templates/catalogue/book_mini_box.html b/src/catalogue/templates/catalogue/book_mini_box.html index 88ec16dfd..d77f91062 100755 --- a/src/catalogue/templates/catalogue/book_mini_box.html +++ b/src/catalogue/templates/catalogue/book_mini_box.html @@ -5,13 +5,13 @@ {% endif %} {% if book.cover_thumb %} - {{ author_str }} – {{ book.title }} + {{ author }} – {{ book.title }} {% endif %} {% if show_lang %} {{ book.language_code }} {% endif %}
- {{ author_str }} + {{ author }} {{ book.title }}
{% if with_link %} diff --git a/src/catalogue/templatetags/catalogue_tags.py b/src/catalogue/templatetags/catalogue_tags.py index 23eeedacc..5064cb6e9 100644 --- a/src/catalogue/templatetags/catalogue_tags.py +++ b/src/catalogue/templatetags/catalogue_tags.py @@ -370,7 +370,7 @@ def plain_list(context, object_list, with_initials=True, by_author=False, choice initial = obj.get_initial().upper() if initial != last_initial: last_initial = initial - names.append((obj.author_str() if by_author else initial, [])) + names.append((obj.author_unicode() if by_author else initial, [])) names[-1][1].append(obj) return locals() diff --git a/src/catalogue/tests/tags.py b/src/catalogue/tests/tags.py index 2ba617e8e..8d651a19b 100644 --- a/src/catalogue/tests/tags.py +++ b/src/catalogue/tests/tags.py @@ -276,7 +276,7 @@ class BookTagsTests(WLTestCase): book = models.Book.objects.get(slug='parent') related_themes = book.related_themes() - self.assertEqual([t.slug for t in book.tags.filter(category='author')], + self.assertEqual([t.slug for t in book.authors()], ['common-man']) self.assertEqual([t.slug for t in book.tags.filter(category='kind')], ['kind']) diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 50dde9f5b..c2636089d 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -609,11 +609,14 @@ class CustomPDFFormView(AjaxableFormView): @ssi_included def book_mini(request, pk, with_link=True): - book = get_object_or_404(models.Book, pk=pk) - author_str = ", ".join(tag.name for tag in book.tags.filter(category='author')) + # book = get_object_or_404(models.Book, pk=pk) + try: + book = models.Book.objects.only('cover_thumb', 'title', 'language', 'slug').get(pk=pk) + except models.Book.DoesNotExist: + raise Http404 return render(request, 'catalogue/book_mini_box.html', { 'book': book, - 'author_str': author_str, + 'author': book.author_unicode(), 'with_link': with_link, 'show_lang': book.language_code() != settings.LANGUAGE_CODE, }) diff --git a/src/opds/views.py b/src/opds/views.py index 001b69d7c..189ff0f5a 100644 --- a/src/opds/views.py +++ b/src/opds/views.py @@ -190,14 +190,14 @@ class AcquisitionFeed(Feed): def item_author_name(self, book): try: - return book.tags.filter(category='author')[0].name - except KeyError: + return book.authors().first().name + except AttributeError: return u'' def item_author_link(self, book): try: - return book.tags.filter(category='author')[0].get_absolute_url() - except KeyError: + return book.authors().first().get_absolute_url() + except AttributeError: return u'' def item_enclosure_url(self, book): diff --git a/src/picture/models.py b/src/picture/models.py index 8ab5d2111..b39661f29 100644 --- a/src/picture/models.py +++ b/src/picture/models.py @@ -112,8 +112,8 @@ class Picture(models.Model): self.sort_key = sortify(self.title)[:120] try: - author = self.tags.filter(category='author')[0].sort_key - except IndexError: + author = self.authors().first().sort_key + except AttributeError: author = u'' self.sort_key_author = author @@ -124,8 +124,11 @@ class Picture(models.Model): def __unicode__(self): return self.title - def author_str(self): - return ", ".join(str(t) for t in self.tags.filter(category='author')) + def authors(self): + return self.tags.filter(category='author') + + def author_unicode(self): + return ", ".join(self.authors().values_list('name', flat=True)) @permalink def get_absolute_url(self): @@ -313,7 +316,7 @@ class Picture(models.Model): pics_by_author[tag] = [] for pic in pics.iterator(): - authors = list(pic.tags.filter(category='author')) + authors = list(pic.authors().only('pk')) if authors: for author in authors: pics_by_author[author].append(pic) @@ -332,9 +335,7 @@ class Picture(models.Model): return self._info def pretty_title(self, html_links=False): - picture = self - names = [(tag.name, tag.get_absolute_url()) - for tag in self.tags.filter(category='author')] + names = [(tag.name, tag.get_absolute_url()) for tag in self.authors().only('name', 'category', 'slug')] names.append((self.title, self.get_absolute_url())) if html_links: diff --git a/src/picture/templates/picture/picture_mini_box.html b/src/picture/templates/picture/picture_mini_box.html index d8ebbf77b..1ad2accb4 100644 --- a/src/picture/templates/picture/picture_mini_box.html +++ b/src/picture/templates/picture/picture_mini_box.html @@ -7,10 +7,10 @@
{% endif %} {% if picture.image_file %} - {{ author_str }} – {{ picture.title }} + {{ author }} – {{ picture.title }} {% endif %}
- {{ author_str }} + {{ author }} {{ picture.title }}
{% if with_link %} diff --git a/src/picture/views.py b/src/picture/views.py index fea5a5eb2..6b83c3501 100644 --- a/src/picture/views.py +++ b/src/picture/views.py @@ -100,10 +100,9 @@ def import_picture(request): @ssi_included def picture_mini(request, pk, with_link=True): picture = get_object_or_404(Picture, pk=pk) - author_str = ", ".join(tag.name for tag in picture.tags.filter(category='author')) return render(request, 'picture/picture_mini_box.html', { 'picture': picture, - 'author_str': author_str, + 'author': picture.author_unicode(), 'with_link': with_link, }) diff --git a/src/wolnelektury/views.py b/src/wolnelektury/views.py index c1792806f..1a6738ba0 100644 --- a/src/wolnelektury/views.py +++ b/src/wolnelektury/views.py @@ -35,10 +35,10 @@ def main_page(request): # pass # FIXME: find this theme and books properly. - if Fragment.objects.count(): + if Fragment.objects.exists(): while True: ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0] - tf = Fragment.tagged.with_any([ctx['theme']]).order_by('?')[:100] + tf = Fragment.tagged.with_any([ctx['theme']]).select_related('book').order_by('?')[:100] if not tf: continue ctx['theme_fragment'] = tf[0] -- 2.20.1