Search by metadata.
authorRadek Czajka <rczajka@rczajka.pl>
Tue, 1 Mar 2022 13:45:49 +0000 (14:45 +0100)
committerRadek Czajka <rczajka@rczajka.pl>
Tue, 1 Mar 2022 13:45:49 +0000 (14:45 +0100)
src/documents/migrations/0007_book_dc.py [new file with mode: 0644]
src/documents/models/book.py
src/documents/templatetags/book_list.py

diff --git a/src/documents/migrations/0007_book_dc.py b/src/documents/migrations/0007_book_dc.py
new file mode 100644 (file)
index 0000000..4daf828
--- /dev/null
@@ -0,0 +1,18 @@
+# Generated by Django 3.1.13 on 2022-03-01 14:11
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('documents', '0006_auto_20210706_0130'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='book',
+            name='dc',
+            field=models.JSONField(editable=False, null=True),
+        ),
+    ]
index d5724a2..e649180 100644 (file)
@@ -3,7 +3,7 @@
 #
 from django.apps import apps
 from django.contrib.sites.models import Site
-from django.db import models, transaction
+from django.db import connection, models, transaction
 from django.template.loader import render_to_string
 from django.urls import reverse
 from django.utils.translation import ugettext_lazy as _
@@ -41,6 +41,7 @@ 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 = models.JSONField(null=True, editable=False)
     catalogue_book = models.ForeignKey(
         'catalogue.Book',
         models.DO_NOTHING,
@@ -68,6 +69,14 @@ class Book(models.Model):
             qs = qs.filter(public=True)
         return qs
 
+    @staticmethod
+    def q_dc(field, field_plural, value, prefix=''):
+        if connection.features.supports_json_field_contains:
+            return models.Q(**{f'{prefix}dc__{field_plural}__contains': value})
+        else:
+            return models.Q(**{f'{prefix}dc__{field}': value})
+            
+    
     # Representing
     # ============
 
@@ -367,6 +376,7 @@ class Book(models.Model):
                 else:
                     if info.cover_source == image.get_full_url():
                         update['dc_cover_image'] = image
+            update['dc'] = info.to_dict()
         Book.objects.filter(pk=self.pk).update(**update)
 
     def touch(self):
index bf5fbd0..88120d2 100644 (file)
@@ -1,12 +1,12 @@
 # This file is part of FNP-Redakcja, licensed under GNU Affero GPLv3 or later.
 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
 #
-from re import split
+import re
 from django.db.models import Q, Count, F, Max
 from django import template
 from django.utils.translation import ugettext_lazy as _
 from django.contrib.auth.models import User
-from documents.models import Chunk, Image, Project
+from documents.models import Book, Chunk, Image, Project
 
 register = template.Library()
 
@@ -70,10 +70,20 @@ def foreign_filter(qs, value, filter_field, model, model_field='slug', unset='-'
 def search_filter(qs, value, filter_fields):
     if not value:
         return qs
-    q = Q(**{"%s__icontains" % filter_fields[0]: value})
-    for field in filter_fields[1:]:
-        q |= Q(**{"%s__icontains" % field: value})
-    return qs.filter(q)
+
+    for word in value.split():
+        m = re.match(r'(.+):(.+)', word)
+        if m is not None:
+            field = m.group(1)
+            value = m.group(2)
+            q = Book.q_dc(field, field + 's', value, 'book__')
+        else:
+            q = Q(**{"%s__icontains" % filter_fields[0]: value})
+            for field in filter_fields[1:]:
+                q |= Q(**{"%s__icontains" % field: value})
+        qs = qs.filter(q)
+
+    return qs
 
 
 _states = [