138 lines
4 KiB
Python
138 lines
4 KiB
Python
|
|
from django.db import models
|
||
|
|
from taggit.managers import TaggableManager
|
||
|
|
|
||
|
|
from wagtail.search import index
|
||
|
|
|
||
|
|
|
||
|
|
class Author(index.Indexed, models.Model):
|
||
|
|
name = models.CharField(max_length=255)
|
||
|
|
date_of_birth = models.DateField(null=True)
|
||
|
|
|
||
|
|
search_fields = [
|
||
|
|
index.SearchField("name"),
|
||
|
|
index.AutocompleteField("name"),
|
||
|
|
index.FilterField("date_of_birth"),
|
||
|
|
]
|
||
|
|
|
||
|
|
def __str__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
|
||
|
|
class Book(index.Indexed, models.Model):
|
||
|
|
title = models.CharField(max_length=255)
|
||
|
|
summary = models.TextField(blank=True)
|
||
|
|
authors = models.ManyToManyField(Author, related_name="books")
|
||
|
|
publication_date = models.DateField()
|
||
|
|
number_of_pages = models.IntegerField()
|
||
|
|
tags = TaggableManager()
|
||
|
|
|
||
|
|
search_fields = [
|
||
|
|
index.SearchField("title", boost=2.0),
|
||
|
|
index.SearchField("summary"),
|
||
|
|
index.AutocompleteField("title"),
|
||
|
|
index.FilterField("title"),
|
||
|
|
index.FilterField("authors"),
|
||
|
|
index.RelatedFields("authors", Author.search_fields),
|
||
|
|
index.FilterField("publication_date"),
|
||
|
|
index.FilterField("number_of_pages"),
|
||
|
|
index.RelatedFields(
|
||
|
|
"tags",
|
||
|
|
[
|
||
|
|
index.SearchField("name"),
|
||
|
|
index.FilterField("slug"),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
index.FilterField("tags"),
|
||
|
|
]
|
||
|
|
|
||
|
|
@classmethod
|
||
|
|
def get_indexed_objects(cls):
|
||
|
|
indexed_objects = super().get_indexed_objects()
|
||
|
|
|
||
|
|
# Don't index books using Book class that they have a more specific type
|
||
|
|
if cls is Book:
|
||
|
|
indexed_objects = indexed_objects.exclude(
|
||
|
|
id__in=Novel.objects.values_list("book_ptr_id", flat=True)
|
||
|
|
)
|
||
|
|
|
||
|
|
indexed_objects = indexed_objects.exclude(
|
||
|
|
id__in=ProgrammingGuide.objects.values_list("book_ptr_id", flat=True)
|
||
|
|
)
|
||
|
|
|
||
|
|
# Exclude Books that have the title "Don't index me!"
|
||
|
|
indexed_objects = indexed_objects.exclude(title="Don't index me!")
|
||
|
|
|
||
|
|
return indexed_objects
|
||
|
|
|
||
|
|
def get_indexed_instance(self):
|
||
|
|
# Check if this object is a Novel or ProgrammingGuide and return the specific object
|
||
|
|
novel = Novel.objects.filter(book_ptr_id=self.id).first()
|
||
|
|
programming_guide = ProgrammingGuide.objects.filter(book_ptr_id=self.id).first()
|
||
|
|
|
||
|
|
# Return the novel/programming guide object if there is one, otherwise return self
|
||
|
|
return novel or programming_guide or self
|
||
|
|
|
||
|
|
def __str__(self):
|
||
|
|
return self.title
|
||
|
|
|
||
|
|
|
||
|
|
class Character(models.Model):
|
||
|
|
name = models.CharField(max_length=255)
|
||
|
|
novel = models.ForeignKey(
|
||
|
|
"Novel", related_name="characters", on_delete=models.CASCADE
|
||
|
|
)
|
||
|
|
|
||
|
|
def __str__(self):
|
||
|
|
return self.name
|
||
|
|
|
||
|
|
|
||
|
|
class Novel(Book):
|
||
|
|
setting = models.CharField(max_length=255)
|
||
|
|
protagonist = models.OneToOneField(
|
||
|
|
Character, related_name="+", null=True, on_delete=models.SET_NULL
|
||
|
|
)
|
||
|
|
|
||
|
|
search_fields = Book.search_fields + [
|
||
|
|
index.SearchField("setting"),
|
||
|
|
index.AutocompleteField("setting"),
|
||
|
|
index.RelatedFields(
|
||
|
|
"characters",
|
||
|
|
[
|
||
|
|
index.SearchField("name", boost=0.25),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
index.RelatedFields(
|
||
|
|
"protagonist",
|
||
|
|
[
|
||
|
|
index.SearchField("name", boost=0.5),
|
||
|
|
index.FilterField("novel"),
|
||
|
|
],
|
||
|
|
),
|
||
|
|
index.FilterField("protagonist"),
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
class ProgrammingGuide(Book):
|
||
|
|
programming_language = models.CharField(
|
||
|
|
max_length=255,
|
||
|
|
choices=[
|
||
|
|
("py", "Python"),
|
||
|
|
("js", "JavaScript"),
|
||
|
|
("rs", "Rust"),
|
||
|
|
],
|
||
|
|
)
|
||
|
|
|
||
|
|
search_fields = Book.search_fields + [
|
||
|
|
index.SearchField("get_programming_language_display"),
|
||
|
|
index.FilterField("programming_language"),
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
class UnindexedBook(index.Indexed, models.Model):
|
||
|
|
title = models.CharField(max_length=255)
|
||
|
|
publication_date = models.DateField()
|
||
|
|
number_of_pages = models.IntegerField()
|
||
|
|
tags = TaggableManager()
|
||
|
|
|
||
|
|
search_fields = []
|