From 4c19c12e4356b74cbdc338da193ba4a47c54ddbf Mon Sep 17 00:00:00 2001 From: Rasika Amaratissa Date: Wed, 21 Aug 2019 11:13:50 +1000 Subject: [PATCH 1/3] Add example for custom lookup fields Use `Tag` model to setup a document viewset using the unique title field as a custom lookup field. --- examples/simple/factories/__init__.py | 1 + .../search_indexes/documents/__init__.py | 2 + .../simple/search_indexes/documents/tag.py | 35 +++++++++++++++++ .../search_indexes/serializers/__init__.py | 2 + .../simple/search_indexes/serializers/tag.py | 19 +++++++++ examples/simple/search_indexes/urls.py | 11 ++++++ .../search_indexes/viewsets/__init__.py | 2 + .../simple/search_indexes/viewsets/tag.py | 39 +++++++++++++++++++ examples/simple/settings/base.py | 1 + 9 files changed, 112 insertions(+) create mode 100644 examples/simple/search_indexes/documents/tag.py create mode 100644 examples/simple/search_indexes/serializers/tag.py create mode 100644 examples/simple/search_indexes/viewsets/tag.py diff --git a/examples/simple/factories/__init__.py b/examples/simple/factories/__init__.py index a0b29ebf..a2ab882a 100644 --- a/examples/simple/factories/__init__.py +++ b/examples/simple/factories/__init__.py @@ -9,3 +9,4 @@ from .books_order import * from .books_orderline import * from .books_publisher import * +from .books_tag import * diff --git a/examples/simple/search_indexes/documents/__init__.py b/examples/simple/search_indexes/documents/__init__.py index 01c1dad1..96952504 100644 --- a/examples/simple/search_indexes/documents/__init__.py +++ b/examples/simple/search_indexes/documents/__init__.py @@ -4,6 +4,7 @@ from .city import CityDocument from .publisher import PublisherDocument from .location import LocationDocument +from .tag import TagDocument __all___ = ( 'AddressDocument', @@ -11,4 +12,5 @@ 'BookDocument', 'CityDocument', 'PublisherDocument', + 'TagDocument', ) diff --git a/examples/simple/search_indexes/documents/tag.py b/examples/simple/search_indexes/documents/tag.py new file mode 100644 index 00000000..86787d8a --- /dev/null +++ b/examples/simple/search_indexes/documents/tag.py @@ -0,0 +1,35 @@ +from django.conf import settings +from django_elasticsearch_dsl import Document, Index, fields + +from books.models import Tag +from .analyzers import html_strip + + +__all__ = ('TagDocument',) + +INDEX = Index(settings.ELASTICSEARCH_INDEX_NAMES[__name__]) + +INDEX.settings( + number_of_shards=1, + number_of_replicas=1, + blocks={'read_only_allow_delete': None} +) + + +@INDEX.doc_type +class TagDocument(Document): + """Elasticsearch document for a Tag.""" + + # Set unique title as the document id. + id = fields.KeywordField(attr='title') + title = fields.KeywordField() + + class Django(object): + """Django Elasticsearch DSL ORM Meta.""" + + model = Tag + + class Meta(object): + """Meta options.""" + + parellel_indexing = True diff --git a/examples/simple/search_indexes/serializers/__init__.py b/examples/simple/search_indexes/serializers/__init__.py index c3e95af9..82ed99e3 100644 --- a/examples/simple/search_indexes/serializers/__init__.py +++ b/examples/simple/search_indexes/serializers/__init__.py @@ -10,6 +10,7 @@ PublisherDocumentSerializer, PublisherDocumentSimpleSerializer, ) +from .tag import TagDocumentSerializer __all__ = ( 'AddressDocumentSerializer', @@ -21,4 +22,5 @@ 'LocationDocumentSerializer', 'PublisherDocumentSerializer', 'PublisherDocumentSimpleSerializer', + 'TagDocumentSerializer', ) diff --git a/examples/simple/search_indexes/serializers/tag.py b/examples/simple/search_indexes/serializers/tag.py new file mode 100644 index 00000000..a902ac8e --- /dev/null +++ b/examples/simple/search_indexes/serializers/tag.py @@ -0,0 +1,19 @@ +from django_elasticsearch_dsl_drf.serializers import DocumentSerializer + +from ..documents import TagDocument + + +__all__ = ('TagDocumentSerializer',) + + +class TagDocumentSerializer(DocumentSerializer): + """Serializer for a Tag document.""" + + class Meta(object): + """Meta options.""" + + document = TagDocument + fields = ( + 'id', + 'title', + ) diff --git a/examples/simple/search_indexes/urls.py b/examples/simple/search_indexes/urls.py index 86d9a4bf..0e8df817 100644 --- a/examples/simple/search_indexes/urls.py +++ b/examples/simple/search_indexes/urls.py @@ -26,6 +26,7 @@ LocationDocumentViewSet, PublisherDocumentViewSet, FrontAddressDocumentViewSet, + TagDocumentViewSet, ) __all__ = ('urlpatterns',) @@ -203,6 +204,16 @@ basename='publisherdocument' ) +# ********************************************************* +# ************************* Tags ************************** +# ********************************************************* + +router.register( + r'tags', + TagDocumentViewSet, + basename='tagdocument' +) + # ********************************************************** # ********************** URL patterns ********************** # ********************************************************** diff --git a/examples/simple/search_indexes/viewsets/__init__.py b/examples/simple/search_indexes/viewsets/__init__.py index c5800e13..0a97691d 100644 --- a/examples/simple/search_indexes/viewsets/__init__.py +++ b/examples/simple/search_indexes/viewsets/__init__.py @@ -23,6 +23,7 @@ from .city import CityDocumentViewSet, CityCompoundSearchBackendDocumentViewSet from .location import LocationDocumentViewSet from .publisher import PublisherDocumentViewSet +from .tag import TagDocumentViewSet __all__ = ( 'AddressDocumentViewSet', @@ -50,4 +51,5 @@ 'LocationDocumentViewSet', 'PublisherDocumentViewSet', 'FrontAddressDocumentViewSet', + 'TagDocumentViewSet', ) diff --git a/examples/simple/search_indexes/viewsets/tag.py b/examples/simple/search_indexes/viewsets/tag.py new file mode 100644 index 00000000..a173bcac --- /dev/null +++ b/examples/simple/search_indexes/viewsets/tag.py @@ -0,0 +1,39 @@ +from django_elasticsearch_dsl_drf.constants import ( + FUNCTIONAL_SUGGESTER_COMPLETION_MATCH, + FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX, + LOOKUP_FILTER_GEO_BOUNDING_BOX, + LOOKUP_FILTER_GEO_DISTANCE, + LOOKUP_FILTER_GEO_POLYGON, + SUGGESTER_COMPLETION, + SUGGESTER_PHRASE, + SUGGESTER_TERM, +) +from django_elasticsearch_dsl_drf.filter_backends import ( + FilteringFilterBackend, + DefaultOrderingFilterBackend, + OrderingFilterBackend, + SearchFilterBackend, + SuggesterFilterBackend, + FunctionalSuggesterFilterBackend, + GeoSpatialFilteringFilterBackend, + GeoSpatialOrderingFilterBackend, +) +from django_elasticsearch_dsl_drf.pagination import LimitOffsetPagination +from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet + +from ..documents import TagDocument +from ..serializers import TagDocumentSerializer + +__all__ = ( + 'TagDocumentViewSet', +) + + +class TagDocumentViewSet(DocumentViewSet): + """Document viewset for tags.""" + + document = TagDocument + serializer_class = TagDocumentSerializer + lookup_field = 'title' + filter_backends = [] + pagination_class = LimitOffsetPagination diff --git a/examples/simple/settings/base.py b/examples/simple/settings/base.py index 72621a00..23fcfde3 100644 --- a/examples/simple/settings/base.py +++ b/examples/simple/settings/base.py @@ -279,6 +279,7 @@ 'search_indexes.documents.address': 'address', 'search_indexes.documents.author': 'author', 'search_indexes.documents.book': 'book', + 'search_indexes.documents.tag': 'tag', 'search_indexes.documents.city': 'city', 'search_indexes.documents.publisher': 'publisher', 'search_indexes.documents.location': 'location', From a1dd1aa6584f6e5fb6d4aa7d0cce939dbb5e1d68 Mon Sep 17 00:00:00 2001 From: Rasika Amaratissa Date: Wed, 21 Aug 2019 11:15:02 +1000 Subject: [PATCH 2/3] Add test case for custom lookup field scenario --- examples/simple/settings/testing.py | 1 + src/django_elasticsearch_dsl_drf/tests/test_views.py | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/examples/simple/settings/testing.py b/examples/simple/settings/testing.py index d98985ec..63a63c64 100644 --- a/examples/simple/settings/testing.py +++ b/examples/simple/settings/testing.py @@ -17,6 +17,7 @@ 'search_indexes.documents.address': 'test_address', 'search_indexes.documents.author': 'test_author', 'search_indexes.documents.book': 'test_book', + 'search_indexes.documents.tag': 'test_tag', 'search_indexes.documents.city': 'test_city', 'search_indexes.documents.publisher': 'test_publisher', 'search_indexes.documents.location': 'test_location', diff --git a/src/django_elasticsearch_dsl_drf/tests/test_views.py b/src/django_elasticsearch_dsl_drf/tests/test_views.py index 4e329424..3cd358da 100644 --- a/src/django_elasticsearch_dsl_drf/tests/test_views.py +++ b/src/django_elasticsearch_dsl_drf/tests/test_views.py @@ -42,6 +42,7 @@ class TestViews(BaseRestFrameworkTestCase): def setUpClass(cls): """Set up class.""" cls.books = factories.BookWithoutTagsAndOrdersFactory.create_batch(20) + cls.tags = factories.TagGenreFactory.create_batch(20) call_command('search_index', '--rebuild', '-f') @@ -70,6 +71,16 @@ def test_detail_view(self): getattr(__obj, __field) ) + def test_detail_view_with_custom_lookup(self): + """Test detail view with a custom lookup field.""" + __obj = self.tags[0] + url = reverse('tagdocument-detail', kwargs={'title': __obj.title}) + data = {} + + response = self.client.get(url, data) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['id'], __obj.title) + if __name__ == '__main__': unittest.main() From d2cd83489f169aaa10b9eb6e6149470a34bc483d Mon Sep 17 00:00:00 2001 From: Rasika Amaratissa Date: Wed, 21 Aug 2019 11:22:45 +1000 Subject: [PATCH 3/3] Remove unused imports --- .../simple/search_indexes/viewsets/tag.py | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/examples/simple/search_indexes/viewsets/tag.py b/examples/simple/search_indexes/viewsets/tag.py index a173bcac..64b24e21 100644 --- a/examples/simple/search_indexes/viewsets/tag.py +++ b/examples/simple/search_indexes/viewsets/tag.py @@ -1,23 +1,3 @@ -from django_elasticsearch_dsl_drf.constants import ( - FUNCTIONAL_SUGGESTER_COMPLETION_MATCH, - FUNCTIONAL_SUGGESTER_COMPLETION_PREFIX, - LOOKUP_FILTER_GEO_BOUNDING_BOX, - LOOKUP_FILTER_GEO_DISTANCE, - LOOKUP_FILTER_GEO_POLYGON, - SUGGESTER_COMPLETION, - SUGGESTER_PHRASE, - SUGGESTER_TERM, -) -from django_elasticsearch_dsl_drf.filter_backends import ( - FilteringFilterBackend, - DefaultOrderingFilterBackend, - OrderingFilterBackend, - SearchFilterBackend, - SuggesterFilterBackend, - FunctionalSuggesterFilterBackend, - GeoSpatialFilteringFilterBackend, - GeoSpatialOrderingFilterBackend, -) from django_elasticsearch_dsl_drf.pagination import LimitOffsetPagination from django_elasticsearch_dsl_drf.viewsets import DocumentViewSet