I have successfully been able to declare, map, and populate all model fields to Elasticsearch Index except the Price field on the BookPrice model which is using through attribute. If I remove the Price field from the document then it works fine.
However, I had successfully been able to build the Index in the past, but I think I made some changes and I lost the code integrity, and it's not working now.
I tried all possible combinations I found on help forums and official documents, but with no luck.
I am currently using
Elasticsearch == 7.8.0
elasticsearch-dsl == 7.2.1
django-elasticsearch-dsl == 7.1.1
models.py
class Publisher(models.Model):
publisher_name = models.CharField(max_length=50)
class BookType(models.Model):
book_type = models.CharField(max_length=20) # Hard Cover, Soft Cover, Kindle Edition, Digital PDF etc.
class Book(models.Model):
book_title = models.TextField()
book_types = models.ManyToManyField(BookType, through='BookPrice', through_fields=('book', 'book_type'))
class BookPrice(models.Model):
book_type = models.ForeignKey(Booktype, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=7, decimal_places=2)
documents.py
@registry.register_document
class BookDocument(Document):
book_title = fields.TextField(
attr='book_title',
fields={
'suggest': fields.CompletionField(),
})
publisher = fields.ObjectField(properties={
'publisher_name': fields.TextField(),
})
book_types = fields.NestedField(properties={
'id': fields.IntegerField(),
'book_type': fields.TextField(),
'price': fields.FloatField()
})
class Index:
name = 'books'
settings = {'number_of_shards': 1,
'number_of_replicas': 0}
class Django:
model = Book
fields = [
'id',
'slug',
'published_date',
'pages',
]
related_models = [BookPrice, BookType]
def get_queryset(self):
return super(BookDocument, self).get_queryset().select_related('publisher', 'book_types')
def get_instances_from_related(self, related_instance):
if isinstance(related_instance, BookPrice):
return related_instance.book
return related_instance.book_set.all()
Errors
Traceback (most recent call last):
File "C:\Users\dev\PycharmProjects\books\venv\lib\site-packages\django_elasticsearch_dsl\fields.py", line 53, in get_value_from_instance
instance = instance[attr]
TypeError: 'BookType' object is not subscriptable
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\dev\PycharmProjects\books\venv\lib\site-packages\django_elasticsearch_dsl\fields.py", line 59, in get_value_from_instance
instance = getattr(instance, attr)
AttributeError: 'BookType' object has no attribute 'price'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\dev\PycharmProjects\books\venv\lib\site-packages\django_elasticsearch_dsl\fields.py", line 64, in get_value_from_instance
instance = instance[int(attr)]
ValueError: invalid literal for int() with base 10: 'price'
File "C:\Users\dev\PycharmProjects\books\venv\lib\site-packages\django_elasticsearch_dsl\fields.py", line 69, in get_value_from_instance
raise VariableLookupError(
django_elasticsearch_dsl.exceptions.VariableLookupError: Failed lookup for key [price] in <BookType: Hard Cover>
Exception ignored in: <generator object cursor_iter at 0x00000000052F07B0>
Traceback (most recent call last):
File "C:\Users\dev\PycharmProjects\books\venv\lib\site-packages\django\db\models\sql\compiler.py", line 1586, in cursor_iter
cursor.close()
sqlite3.ProgrammingError: Cannot operate on a closed database.