I am facing this error while calling Viewset for book document.
http://localhost:8000/search/books/
Error:
Request Method: | GET
-- | --
http://localhost:8000/search/books/
1.11.1
**AttributeError
'Search' object has no attribute 'model'**
/home/hasher/elastic_search_django-drf/venv/local/lib/python2.7/site-packages/rest_framework/permissions.py in has_permission, line 133
/home/hasher/elastic_search_django-drf/venv/bin/python
2.7.12
['/home/hasher/elastic_search_django-drf/es-dsl-drf-demo', '/home/hasher/elastic_search_django-drf', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7/plat-x86_64-linux-gnu', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7/lib-tk', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7/lib-old', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7/lib-dynload', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/home/hasher/elastic_search_django-drf/venv/local/lib/python2.7/site-packages', '/home/hasher/elastic_search_django-drf/venv/lib/python2.7/site-packages']
Mon, 16 Apr 2018 07:53:13 +0000
I am using:
certifi==2018.1.18
chardet==3.0.4
coreapi==2.3.3
coreschema==0.0.4
coverage==4.4.1
dj-database-url==0.4.2
dj-email-url==0.0.10
Django==1.11.1
django-coverage-plugin==1.4.2
django-elasticsearch-dsl==0.4.4
django-elasticsearch-dsl-drf==0.7.1
django-filter==1.0.2
django-nine==0.1.13
django-rest-swagger==2.1.2
djangorestframework==3.6.3
drf-extensions==0.3.1
elasticsearch==5.5.2
elasticsearch-dsl==5.1.0
gunicorn==19.7.1
idna==2.6
ipaddress==1.0.21
itypes==1.1.0
Jinja2==2.10
Logentries==0.17
MarkupSafe==1.0
openapi-codec==1.3.2
python-dateutil==2.7.2
pytz==2018.4
requests==2.18.4
simplejson==3.13.2
six==1.11.0
uritemplate==3.0.0
urllib3==1.22
whitenoise==3.3.0
also,
Here are my models:
book.py
from django.conf import settings
from django.db import models
from .tag import *
from .author import *
from six import python_2_unicode_compatible
BOOK_PUBLISHING_STATUS_PUBLISHED = 'published'
BOOK_PUBLISHING_STATUS_NOT_PUBLISHED = 'not_published'
BOOK_PUBLISHING_STATUS_IN_PROGRESS = 'in_progress'
BOOK_PUBLISHING_STATUS_CANCELLED = 'cancelled'
BOOK_PUBLISHING_STATUS_REJECTED = 'rejected'
BOOK_PUBLISHING_STATUS_CHOICES = (
(BOOK_PUBLISHING_STATUS_PUBLISHED, "Published"),
(BOOK_PUBLISHING_STATUS_NOT_PUBLISHED, "Not published"),
(BOOK_PUBLISHING_STATUS_IN_PROGRESS, "In progress"),
(BOOK_PUBLISHING_STATUS_CANCELLED, "Cancelled"),
(BOOK_PUBLISHING_STATUS_REJECTED, "Rejected"),
)
BOOK_PUBLISHING_STATUS_DEFAULT = BOOK_PUBLISHING_STATUS_PUBLISHED
@python_2_unicode_compatible
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
latitude = models.DecimalField(null=True,
blank=True,
decimal_places=15,
max_digits=19,
default=0)
longitude = models.DecimalField(null=True,
blank=True,
decimal_places=15,
max_digits=19,
default=0)
class Meta(object):
ordering = ["id"]
def __str__(self):
return self.name
@property
def location_field_indexing(self):
return {
'lat': self.latitude,
'lon': self.longitude,
}
@python_2_unicode_compatible
class Book(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(null=True, blank=True)
summary = models.TextField(null=True, blank=True)
authors = models.ManyToManyField(Author, related_name='books')
publisher = models.ForeignKey(Publisher, related_name='books')
publication_date = models.DateField()
state = models.CharField(max_length=100,
choices=BOOK_PUBLISHING_STATUS_CHOICES,
default=BOOK_PUBLISHING_STATUS_DEFAULT)
isbn = models.CharField(max_length=100, unique=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
pages = models.PositiveIntegerField(default=200)
stock_count = models.PositiveIntegerField(default=30)
tags = models.ManyToManyField(Tag,
related_name='books',
blank=True)
class Meta(object):
"""Meta options."""
ordering = ["isbn"]
def __str__(self):
return self.title
# The only publisher information we're going to need in our document
# is the publisher name. Since publisher isn't a required field,
# we define a properly on a model level to avoid indexing errors on
# non-existing relation.
@property
def publisher_indexing(self):
if self.publisher is not None:
return self.publisher.name
# As of tags, again, we only need a flat list of tag names, on which
# we can filter. Therefore, we define a properly on a model level,
# which will return a JSON dumped list of tags relevant to the
# current book model object.
@property
def tags_indexing(self):
return [tag.title for tag in self.tags.all()]
here is my document:
documents/book.py
from django_elasticsearch_dsl import DocType, Index, fields
from elasticsearch_dsl import analyzer
from ..models import *
# Name of the Elasticsearch index
INDEX = Index('books')
# See Elasticsearch Indices API reference for available settings
INDEX.settings(
number_of_shards=1,
number_of_replicas=1
)
html_strip = analyzer(
'html_strip',
tokenizer="standard",
filter=["standard", "lowercase", "stop", "snowball"],
char_filter=["html_strip"]
)
@INDEX.doc_type
class BookDocument(DocType):
"""Book Elasticsearch document."""
id = fields.IntegerField(attr='id')
title = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
description = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
summary = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
publisher = fields.StringField(
attr='publisher_indexing',
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
publication_date = fields.DateField()
state = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
isbn = fields.StringField(
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword'),
}
)
price = fields.FloatField()
pages = fields.IntegerField()
stock_count = fields.IntegerField()
tags = fields.StringField(
attr='tags_indexing',
analyzer=html_strip,
fields={
'raw': fields.StringField(analyzer='keyword', multi=True),
'suggest': fields.CompletionField(multi=True),
},
multi=True
)
class Meta(object):
"""Meta options."""
model = Book # The model associate with this DocType
here is my serializer:
I am using BookDocumentSimpleSerializer however its showing same error for other serializers too.
serializers/book.py
from rest_framework import serializers
from django_elasticsearch_dsl_drf.serializers import DocumentSerializer
from ..documents import BookDocument
class BookDocumentSerializer1(serializers.Serializer):
"""Serializer for the Book document."""
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(read_only=True)
description = serializers.CharField(read_only=True)
summary = serializers.CharField(read_only=True)
publisher = serializers.CharField(read_only=True)
publication_date = serializers.DateField(read_only=True)
state = serializers.CharField(read_only=True)
isbn = serializers.CharField(read_only=True)
price = serializers.FloatField(read_only=True)
pages = serializers.IntegerField(read_only=True)
stock_count = serializers.IntegerField(read_only=True)
tags = serializers.SerializerMethodField()
# Used in testing of `isnull` functional filter.
null_field = serializers.CharField(read_only=True,
required=False,
allow_blank=True)
class Meta(object):
"""Meta options."""
fields = (
'id',
'title',
'description',
'summary',
'publisher',
'publication_date',
'state',
'isbn',
'price',
'pages',
'stock_count',
'tags',
'null_field', # Used in testing of `isnull` functional filter.
)
read_only_fields = fields
def create(self, validated_data):
"""Create.
Do nothing.
:param validated_data:
:return:
"""
def update(self, instance, validated_data):
"""Update.
Do nothing.
:param instance:
:param validated_data:
:return:
"""
def get_tags(self, obj):
"""Get tags."""
if obj.tags:
return list(obj.tags)
else:
return []
class BookDocumentSerializer2(serializers.Serializer):
"""Serializer for the Book document."""
id = serializers.IntegerField(read_only=True)
title = serializers.CharField(read_only=True)
description = serializers.CharField(read_only=True)
summary = serializers.CharField(read_only=True)
publisher = serializers.CharField(read_only=True)
publication_date = serializers.DateField(read_only=True)
state = serializers.CharField(read_only=True)
isbn = serializers.CharField(read_only=True)
price = serializers.FloatField(read_only=True)
pages = serializers.IntegerField(read_only=True)
stock_count = serializers.IntegerField(read_only=True)
tags = serializers.SerializerMethodField()
class Meta(object):
"""Meta options."""
# List the serializer fields. Note, that the order of the fields
# is preserved in the ViewSet.
fields = (
'id',
'title',
'description',
'summary',
'publisher',
'publication_date',
'state',
'isbn',
'price',
'pages',
'stock_count',
'tags',
)
def get_tags(self, obj):
"""Get tags."""
if obj.tags:
return list(obj.tags)
else:
return []
class BookDocumentSimpleSerializer(DocumentSerializer):
"""Serializer for the Book document."""
# tags = serializers.SerializerMethodField()
# authors = serializers.SerializerMethodField()
highlight = serializers.SerializerMethodField()
class Meta(object):
"""Meta options."""
document = BookDocument
fields = (
'id',
'title',
'description',
'summary',
'authors',
'publisher',
'publication_date',
'state',
'isbn',
'price',
'pages',
'stock_count',
'tags',
'highlight', # Used in highlight tests
'null_field', # Used in testing of `isnull` functional filter.
)
def get_highlight(self, obj):
if hasattr(obj.meta, 'highlight'):
return obj.meta.highlight.__dict__['_d_']
return {}
here is my viewset:
viewsets/book.py
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_RANGE,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
LOOKUP_QUERY_EXCLUDE,
)
from django_elasticsearch_dsl_drf.filter_backends import (
FilteringFilterBackend,
IdsFilterBackend,
OrderingFilterBackend,
DefaultOrderingFilterBackend,
SearchFilterBackend,
)
from django_elasticsearch_dsl_drf.views import BaseDocumentViewSet
from ..documents import BookDocument
from ..serializers import BookDocumentSimpleSerializer
class BookDocumentView(BaseDocumentViewSet):
"""The BookDocument view."""
document = BookDocument
serializer_class = BookDocumentSimpleSerializer
lookup_field = 'id'
filter_backends = [
FilteringFilterBackend,
IdsFilterBackend,
OrderingFilterBackend,
DefaultOrderingFilterBackend,
SearchFilterBackend,
]
# Define search fields
search_fields = (
'title',
'description',
'summary',
)
# Define filter fields
filter_fields = {
'id': {
'field': 'id',
# Note, that we limit the lookups of id field in this example,
# to `range`, `in`, `gt`, `gte`, `lt` and `lte` filters.
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'title': 'title.raw',
'publisher': 'publisher.raw',
'publication_date': 'publication_date',
'state': 'state.raw',
'isbn': 'isbn.raw',
'price': {
'field': 'price.raw',
# Note, that we limit the lookups of `price` field in this
# example, to `range`, `gt`, `gte`, `lt` and `lte` filters.
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'pages': {
'field': 'pages',
# Note, that we limit the lookups of `pages` field in this
# example, to `range`, `gt`, `gte`, `lt` and `lte` filters.
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'stock_count': {
'field': 'stock_count',
# Note, that we limit the lookups of `stock_count` field in
# this example, to `range`, `gt`, `gte`, `lt` and `lte`
# filters.
'lookups': [
LOOKUP_FILTER_RANGE,
LOOKUP_QUERY_GT,
LOOKUP_QUERY_GTE,
LOOKUP_QUERY_LT,
LOOKUP_QUERY_LTE,
],
},
'tags': {
'field': 'tags',
# Note, that we limit the lookups of `tags` field in
# this example, to `terms, `prefix`, `wildcard`, `in` and
# `exclude` filters.
'lookups': [
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_EXCLUDE,
],
},
'tags.raw': {
'field': 'tags.raw',
# Note, that we limit the lookups of `tags.raw` field in
# this example, to `terms, `prefix`, `wildcard`, `in` and
# `exclude` filters.
'lookups': [
LOOKUP_FILTER_TERMS,
LOOKUP_FILTER_PREFIX,
LOOKUP_FILTER_WILDCARD,
LOOKUP_QUERY_IN,
LOOKUP_QUERY_EXCLUDE,
],
},
}
# Define ordering fields
ordering_fields = {
'id': 'id',
'title': 'title.raw',
'price': 'price.raw',
'state': 'state.raw',
'publication_date': 'publication_date',
}
# Specify default ordering
ordering = ('id', 'title', 'price',)
here is my urls.py:
from rest_framework_extensions.routers import ExtendedDefaultRouter
from .viewsets import BookDocumentView
from .views import titleQuery
router = ExtendedDefaultRouter()
books = router.register(r'books',
BookDocumentView,
base_name='bookdocument')
urlpatterns = [
url(r'^', include(router.urls)),
]
I have tried rebuilding all indexes too but it doesn't worked after that too.