class TextIndex(indexes.SearchIndex, indexes.Indexable): """ Index annotatable texts. """ text = indexes.CharField(document=True, use_template=False) title = indexes.EdgeNgramField(model_attr='title', indexed=False) created = indexes.DateField(model_attr='created', faceted=True, indexed=False, null=True) added = indexes.DateField(model_attr='added', faceted=True, indexed=False) addedBy = indexes.CharField(model_attr='addedBy') uri = indexes.CharField(model_attr='id') relation_count = indexes.CharField(model_attr='relation_count') collections = indexes.MultiValueField(indexed=False, faceted=True, null=True) def get_model(self): """ Get model to be used for indexing """ return Text def index_queryset(self, using=None): """ Used when entire index for model is updated """ return self.get_model().objects.all() def prepare_text(self, instance): return instance.title def prepare_added(self, instance): return instance.added.date() def prepare_collections(self, instance): return [c.id for c in instance.partOf.all()]
class BudgetIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) period_start = indexes.DateField(model_attr='period_start') period_end = indexes.DateField(model_attr='period_end') def get_model(self): return Budget
class MediaIndex(indexes.SearchIndex): is_public = indexes.BooleanField(default=True) datatype = indexes.CharField(model_attr='datatype') author = indexes.MultiValueField(faceted=True) tag = indexes.MultiValueField(faceted=True) taxon = indexes.MultiValueField(faceted=True) tour = indexes.MultiValueField() size = indexes.IntegerField(model_attr='size__id', default=0, faceted=True) sublocation = indexes.CharField(model_attr='sublocation__id', default=0, faceted=True) city = indexes.CharField(model_attr='city__id', default=0, faceted=True) state = indexes.CharField(model_attr='state__id', default=0, faceted=True) country = indexes.CharField(model_attr='country__id', default=0, faceted=True) stats__pageviews = indexes.IntegerField(model_attr='stats__pageviews', default=0) timestamp = indexes.DateField(model_attr='timestamp', null=True) date = indexes.DateField(model_attr='date', null=True) pub_date = indexes.DateField(model_attr='pub_date', null=True) id = indexes.IntegerField(model_attr='id') highlight = indexes.BooleanField(model_attr='highlight', default=False) title_en = indexes.CharField(model_attr='title_en') title = indexes.CharField(model_attr='title_pt') thumb = indexes.CharField(model_attr='thumb_filepath') url = indexes.CharField(model_attr='get_absolute_url') # def prepare_author(self, media): return [author.id for author in media.author_set.all() ]# "%s##%s" % ( author.slug, author.name,) for author in media.author_set.all() ]#Author.objects.filter(images__pk = object.pk)] # def prepare_tag(self, media): return [tag.id for tag in media.tag_set.all() ] #Tag.objects.filter(images__pk = object.pk)] def prepare_taxon(self, media): return [taxon.id for taxon in media.taxon_set.all() ]#Taxon.objects.filter(images__pk = object.pk)] def prepare_tour(self, media): return [tour.id for tour in media.tour_set.all() ]#Taxon.objects.filter(images__pk = object.pk)] def index_queryset(self): """Used when the entire index for model is updated.""" return self.get_model().objects.filter(is_public=True) #select_related('author', 'tag', 'taxon', 'size', 'sublocation', 'city', 'state', 'country', 'rights') def prepare(self, obj): """ Fetches and adds/alters data before indexing. """ self.prepared_data = super(MediaIndex, self).prepare(obj) u = type(unicode()) for key, data in self.prepared_data.items(): if type(data) == u: self.prepared_data[key] = strip_accents(data) return self.prepared_data
class LiveXapianMockSearchIndex(indexes.SearchIndex): text = indexes.CharField(document=True, use_template=True) name = indexes.CharField(model_attr='author') pub_date = indexes.DateField(model_attr='pub_date') created = indexes.DateField() title = indexes.CharField() def get_model(self): return MockModel
class MinutesIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, model_attr='fulltext') date_taken = indexes.DateField(null=True) order_date = indexes.DateField(model_attr='date_taken') def get_model(self): return LegMinutes def get_updated_field(self): return 'updated_datetime'
class BlogSearchIndex(indexes.SearchIndex): text = indexes.CharField( document=True, use_template=True, template_name="search/indexes/core/mockmodel_text.txt", ) name = indexes.CharField(model_attr="author", faceted=True) date = indexes.DateField(model_attr="date") datetime = indexes.DateField(model_attr="datetime") number = indexes.IntegerField(model_attr="number") boolean = indexes.BooleanField(model_attr="boolean") # slug = indexes.CharField(indexed=False, model_attr="slug") float_number = indexes.FloatField(model_attr="float_number") month = indexes.CharField(indexed=False) url = indexes.CharField(model_attr="url") empty = indexes.CharField() # Various MultiValueFields sites = indexes.MultiValueField() tags = indexes.MultiValueField() keys = indexes.MultiValueField() titles = indexes.MultiValueField() def get_model(self): return models.BlogEntry def prepare_sites(self, obj): return ["%d" % (i * obj.id) for i in range(1, 4)] def prepare_tags(self, obj): if obj.id == 1: return ["a", "b", "c"] elif obj.id == 2: return ["ab", "bc", "cd"] else: return ["an", "to", "or"] def prepare_keys(self, obj): return [i * obj.id for i in range(1, 4)] def prepare_titles(self, obj): if obj.id == 1: return ["object one title one", "object one title two"] elif obj.id == 2: return ["object two title one", "object two title two"] else: return ["object three title one", "object three title two"] def prepare_month(self, obj): return "%02d" % obj.date.month def prepare_empty(self, obj): return ""
class XapianMockSearchIndex(indexes.SearchIndex): text = indexes.CharField( document=True, use_template=True, template_name='search/indexes/core/mockmodel_text.txt') name = indexes.CharField(model_attr='author', faceted=True) pub_date = indexes.DateField(model_attr='pub_date') exp_date = indexes.DateField(model_attr='exp_date') value = indexes.IntegerField(model_attr='value') flag = indexes.BooleanField(model_attr='flag') slug = indexes.CharField(indexed=False, model_attr='slug') popularity = indexes.FloatField(model_attr='popularity') month = indexes.CharField(indexed=False) url = indexes.CharField(model_attr='url') empty = indexes.CharField() # Various MultiValueFields sites = indexes.MultiValueField() tags = indexes.MultiValueField() keys = indexes.MultiValueField() titles = indexes.MultiValueField() def get_model(self): return XapianMockModel def prepare_sites(self, obj): return ['%d' % (i * obj.id) for i in range(1, 4)] def prepare_tags(self, obj): if obj.id == 1: return ['a', 'b', 'c'] elif obj.id == 2: return ['ab', 'bc', 'cd'] else: return ['an', 'to', 'or'] def prepare_keys(self, obj): return [i * obj.id for i in range(1, 4)] def prepare_titles(self, obj): if obj.id == 1: return ['object one title one', 'object one title two'] elif obj.id == 2: return ['object two title one', 'object two title two'] else: return ['object three title one', 'object three title two'] def prepare_month(self, obj): return '%02d' % obj.pub_date.month def prepare_empty(self, obj): return ''
class BlogSearchIndex(indexes.SearchIndex): text = indexes.CharField( document=True, use_template=True, template_name='search/indexes/core/mockmodel_text.txt' ) name = indexes.CharField(model_attr='author', faceted=True) date = indexes.DateField(model_attr='date') datetime = indexes.DateField(model_attr='datetime') number = indexes.IntegerField(model_attr='number') boolean = indexes.BooleanField(model_attr='boolean') #slug = indexes.CharField(indexed=False, model_attr='slug') float_number = indexes.FloatField(model_attr='float_number') month = indexes.CharField(indexed=False) url = indexes.CharField(model_attr='url') empty = indexes.CharField() # Various MultiValueFields sites = indexes.MultiValueField() tags = indexes.MultiValueField() keys = indexes.MultiValueField() titles = indexes.MultiValueField() def get_model(self): return models.BlogEntry def prepare_sites(self, obj): return ['%d' % (i * obj.id) for i in range(1, 4)] def prepare_tags(self, obj): if obj.id == 1: return ['a', 'b', 'c'] elif obj.id == 2: return ['ab', 'bc', 'cd'] else: return ['an', 'to', 'or'] def prepare_keys(self, obj): return [i * obj.id for i in range(1, 4)] def prepare_titles(self, obj): if obj.id == 1: return ['object one title one', 'object one title two'] elif obj.id == 2: return ['object two title one', 'object two title two'] else: return ['object three title one', 'object three title two'] def prepare_month(self, obj): return '%02d' % obj.date.month def prepare_empty(self, obj): return ''
class SemesterIndex(indexes.SearchIndex, indexes.Indexable): """ Index for semesters. """ text = indexes.EdgeNgramField(document=True, use_template=True) season = indexes.EdgeNgramField(model_attr='season', boost=2) year = indexes.EdgeNgramField(model_attr='year', boost=2) start_date = indexes.DateField(model_attr='start_date') end_date = indexes.DateField(model_attr='end_date') def get_model(self): return Semester def index_queryset(self, using=None): return self.get_model().objects.all()
class BillIndex(SearchIndex): text = indexes.CharField(document=True, model_attr='name') sci = indexes.CharField(stored=False, use_template=True) number = indexes.CharField(model_attr='number', indexed=False) url = indexes.CharField(model_attr='get_absolute_url', indexed=False) date = indexes.DateField(model_attr='session__start') session = indexes.CharField(model_attr='session', indexed=False)
class AllTypesWhooshMockSearchIndex(indexes.SearchIndex): text = indexes.CharField(document=True, use_template=True) name = indexes.CharField(model_attr='author', indexed=False) pub_date = indexes.DateField(model_attr='pub_date') sites = indexes.MultiValueField() seen_count = indexes.IntegerField(indexed=False) is_active = indexes.BooleanField(default=True)
class VoteIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) uid = indexes.CharField(model_attr='uid') category = indexes.CharField(default=None, model_attr='category') content = indexes.CharField(model_attr='content') conflict = indexes.BooleanField(default=None, model_attr='conflict') ad = indexes.IntegerField(model_attr='sitting__ad') date = indexes.DateField(model_attr='sitting__date') vote_seq = indexes.CharField(model_attr='vote_seq') result = indexes.CharField(model_attr='result') results = indexes.CharField(model_attr='results') tags = indexes.MultiValueField() tags_num = indexes.IntegerField() def get_model(self): return Vote def prepare_tags(self, obj): return [ (x.title, x.votes, ) for x in Standpoint.objects.filter(vote=obj)\ .annotate(votes=Count('user_standpoint__id'))\ .order_by('-votes') ] def prepare_tags_num(self, obj): return Standpoint.objects.filter(vote=obj)\ .count()
class MockPersonIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) firstname = indexes.CharField(model_attr="firstname", faceted=True) lastname = indexes.CharField(model_attr="lastname", faceted=True) birthdate = indexes.DateField(model_attr="birthdate", faceted=True) letters = indexes.MultiValueField(faceted=True) full_name = indexes.CharField() description = indexes.CharField() autocomplete = indexes.EdgeNgramField() created = indexes.FacetDateTimeField(model_attr="created") @staticmethod def prepare_full_name(obj): return " ".join((obj.firstname, obj.lastname)) @staticmethod def prepare_letters(obj): return [x for x in obj.firstname] @staticmethod def prepare_description(obj): return " ".join((obj.firstname, "is a nice chap!")) @staticmethod def prepare_autocomplete(obj): return " ".join((obj.firstname, obj.lastname)) def get_model(self): return MockPerson def index_queryset(self, using=None): return self.get_model().objects.filter(created__lte=timezone.now())
class RecordIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) date = indexes.DateField(indexed=True, model_attr="date") title_display = indexes.CharField(indexed=False, stored=True, model_attr='title') date_display = indexes.CharField(indexed=False, stored=True, model_attr='date') place_display = indexes.CharField(indexed=False, stored=True) doc_id = indexes.CharField(indexed=False, stored=True, model_attr='doc_name') # Facets place = indexes.CharField(null=True, faceted=True) associated_people = indexes.MultiValueField(null=True, faceted=True) associated_corporations = indexes.MultiValueField(null=True, faceted=True) countries = indexes.MultiValueField(null=True, faceted=True) subject_people = indexes.MultiValueField(null=True, faceted=True) subject_corporations = indexes.MultiValueField(null=True, faceted=True) def get_model(self): return FECEntity def prepare_associated_people(self, obj): values = [] for ap in obj.associated_people.all(): values.append(ap.person) return values def prepare_associated_corporations(self, obj): values = [] for ac in obj.associated_corporations.all(): values.append(ac.corporation) return values def prepare_subject_people(self, obj): values = [] for sp in obj.subject_people.all(): values.append(sp.person) return values def prepare_subject_corporations(self, obj): values = [] for sc in obj.subject_corporations.all(): values.append(sc.corporation) return values def prepare_countries(self, obj): values = [] for c in obj.countries.all(): values.append(c.country) return values def prepare_place(self, obj): return obj.place.place def prepare_place_display(self, obj): return obj.place.place
class SolrRoundTripSearchIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, default='') name = indexes.CharField() is_active = indexes.BooleanField() post_count = indexes.IntegerField() average_rating = indexes.FloatField() price = indexes.DecimalField() pub_date = indexes.DateField() created = indexes.DateTimeField() tags = indexes.MultiValueField() sites = indexes.MultiValueField() def get_model(self): return MockModel def prepare(self, obj): prepped = super(SolrRoundTripSearchIndex, self).prepare(obj) prepped.update({ 'text': 'This is some example text.', 'name': 'Mister Pants', 'is_active': True, 'post_count': 25, 'average_rating': 3.6, 'price': Decimal('24.99'), 'pub_date': datetime.date(2009, 11, 21), 'created': datetime.datetime(2009, 11, 21, 21, 31, 00), 'tags': ['staff', 'outdoor', 'activist', 'scientist'], 'sites': [3, 5, 1], }) return prepped
class TicketIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) about = indexes.CharField(model_attr='about') start_datetime = indexes.DateTimeField(model_attr='start_datetime') start_date = indexes.DateField(model_attr='start_date') location = indexes.CharField(model_attr='location') ticket_type = indexes.CharField(model_attr='ticket_type') payment_method = indexes.CharField(model_attr='payment_method') status = indexes.CharField(model_attr='status') poster_rating = indexes.IntegerField(model_attr='rating', null=True, ) price = indexes.IntegerField(model_attr='price') def get_model(self): return Ticket def index_queryset(self, using=None): """Used when the entire index for model is updated.""" return self.get_model().objects.all()
class WhooshRoundTripSearchIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, default="") name = indexes.CharField() is_active = indexes.BooleanField() post_count = indexes.IntegerField() average_rating = indexes.FloatField() price = indexes.DecimalField() pub_date = indexes.DateField() created = indexes.DateTimeField() tags = indexes.MultiValueField() sites = indexes.MultiValueField() # For a regression involving lists with nothing in them. empty_list = indexes.MultiValueField() def get_model(self): return MockModel def prepare(self, obj): prepped = super().prepare(obj) prepped.update( { "text": "This is some example text.", "name": "Mister Pants", "is_active": True, "post_count": 25, "average_rating": 3.6, "price": Decimal("24.99"), "pub_date": date(2009, 11, 21), "created": datetime(2009, 11, 21, 21, 31, 00), "tags": ["staff", "outdoor", "activist", "scientist"], "sites": [3, 5, 1], "empty_list": [], } ) return prepped
class ReceivedAwardIndex(ObjectIndex, indexes.SearchIndex, indexes.Indexable): text = indexes.CharField( document=True, use_template=True, template_name='search/indexes/gcd/received_award_text.txt') name = indexes.CharField(model_attr="award_name", boost=DEFAULT_BOOST) facet_model_name = indexes.CharField(faceted=True) year = indexes.IntegerField() date = indexes.DateField(faceted=True) sort_name = indexes.CharField(model_attr='award_name', indexed=False) def prepare_year(self, obj): if obj.award_year: return obj.award_year else: return 9999 def prepare_date(self, obj): if obj.award_year: try: return date(obj.award_year, 1, 1) except ValueError: return None else: return None def get_model(self): return ReceivedAward def prepare_facet_model_name(self, obj): return "received award"
class PublicationIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.NgramField(document=True, use_template=True) title = indexes.NgramField(model_attr='titre') bureaux = indexes.FacetMultiValueField(null=True, stored=True) annee = indexes.FacetField(stored=True, null=True) section = indexes.FacetField(stored=True, null=True) date_pub = indexes.DateField(model_attr='date_pub', null=True) def prepare_bureaux(self, obj): try: return [b.nom for b in obj.bureau.all()] except ObjectDoesNotExist as e: print(e) return [u'Non précisé'] def prepare_annee(self, obj): if obj.date_pub is not None: return str(obj.date_pub.year) def get_model(self): return Publication def prepare_section(self, obj): return u"Publication" def index_queryset(self, using=None): return Publication.objects.filter( status__in=[3, 5, 6]).order_by("date_pub")
class PatronIndex(indexes.Indexable, indexes.SearchIndex): text = indexes.CharField(document=True, use_template=False) location = indexes.LocationField(model_attr='default_address__position', null=True) username = indexes.CharField(model_attr='username') avatar = indexes.CharField(null=True) sites = indexes.MultiValueField(faceted=True) date_joined_date = indexes.DateField(model_attr='date_joined__date') url = indexes.CharField(model_attr='get_absolute_url') def get_updated_field(self): return "date_joined_date" def prepare_sites(self, obj): return tuple(obj.sites.values_list('id', flat=True)) def prepare_avatar(self, obj): # FIXME: should we really check for obj.avatar here? return obj.thumbnail.url if obj.avatar and obj.thumbnail else None def get_model(self): return Patron def index_queryset(self, using=None): return self.get_model().on_site.select_related( 'default_address__position')
class SolrMaintainTypeMockSearchIndex(indexes.SearchIndex): text = indexes.CharField(document=True, use_template=True) month = indexes.CharField(indexed=False) pub_date = indexes.DateField(model_attr='pub_date') def prepare_month(self, obj): return "%02d" % obj.pub_date.month
class SolrMockModelSearchIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(model_attr='foo', document=True) name = indexes.CharField(model_attr='author') pub_date = indexes.DateField(model_attr='pub_date') def get_model(self): return MockModel
class SolrAnotherMockModelSearchIndex(indexes.SearchIndex): text = indexes.CharField(document=True) name = indexes.CharField(model_attr='author') pub_date = indexes.DateField(model_attr='pub_date') def prepare_text(self, obj): return u"You might be searching for the user %s" % obj.author
class WhooshMockSearchIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) name = indexes.CharField(model_attr='author') pub_date = indexes.DateField(model_attr='pub_date') def get_model(self): return MockModel
class MediaCorpusIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) #item_acces = indexes.CharField(model_attr='public_access', faceted=True) #item_status = indexes.CharField(model_attr='document_status', faceted=True) digitized = indexes.BooleanField(default=False, faceted=True) #media_type = indexes.CharField(model_attr='media_type', null='None', faceted=True) #recording_context = indexes.CharField(model_attr='recording_context', default='', faceted=True) #physical_format = indexes.CharField(model_attr='collection__physical_format', default='', faceted=True) #content_auto = indexes.EdgeNgramField(model_attr='content') #advance search title = indexes.CharField(model_attr='title') code = KeywordField(model_attr='code', default='') #location_principal = indexes.CharField(default='', boost=1.05) #location_relation = indexes.CharField() #ethnic_group = indexes.CharField(default='') #instruments = indexes.NgramField(default='') #collectors = indexes.NgramField(model_attr='collector', default='') #recorded_from_date = indexes.DateField(model_attr='recorded_from_year', null=True) recorded_to_date = indexes.DateField(model_attr='recorded_to_year', null=True) #year_published = indexes.IntegerField(model_attr='year_published', default='') def prepare_digitized(self, obj): return obj.has_mediafile def get_model(self): return MediaCorpus
class BookIndex(indexes.SearchIndex, indexes.Indexable): abstract = indexes.CharField(model_attr='abstract') name = indexes.CharField(model_attr='name') text = indexes.CharField(document=True) pages = indexes.IntegerField(model_attr='pages', faceted=True) price = indexes.DecimalField(model_attr='price', faceted=True) rating = indexes.FloatField(model_attr='rating', faceted=True) book_id = indexes.CharField(model_attr='id', faceted=False) pubdate = indexes.DateField(model_attr='pubdate', faceted=True) category = indexes.CharField(model_attr='category', faceted=True) publisher = indexes.CharField(model_attr='publisher', faceted=True) pub_year = indexes.CharField(faceted=True) def get_model(self): return Book def index_queryset(self, using=None): return self.get_model().objects.all() def prepare_author_set(self, obj): return [author.name for author in obj.authors.all().order_by('-name')] def prepare_pub_year(self, obj): return obj.pubdate.year def prepare_text(self, obj): return u'{} {}'.format(obj.name, obj.abstract)
class MovieIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) director = indexes.CharField(model_attr='director__name') release_date = indexes.DateField(model_attr='release_date') def get_model(self): return Movie
class WhooshRoundTripSearchIndex(indexes.SearchIndex): text = indexes.CharField(document=True, default='') name = indexes.CharField() is_active = indexes.BooleanField() post_count = indexes.IntegerField() average_rating = indexes.FloatField() pub_date = indexes.DateField() created = indexes.DateTimeField() tags = indexes.MultiValueField() sites = indexes.MultiValueField() # For a regression involving lists with nothing in them. empty_list = indexes.MultiValueField() def prepare(self, obj): prepped = super(WhooshRoundTripSearchIndex, self).prepare(obj) prepped.update({ 'text': 'This is some example text.', 'name': 'Mister Pants', 'is_active': True, 'post_count': 25, 'average_rating': 3.6, 'pub_date': date(2009, 11, 21), 'created': datetime(2009, 11, 21, 21, 31, 00), 'tags': ['staff', 'outdoor', 'activist', 'scientist'], 'sites': [3, 5, 1], 'empty_list': [], }) return prepped
class EventIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) categories = indexes.FacetMultiValueField() title = indexes.CharField(model_attr='title') end_date = indexes.DateField( model_attr='end_date', default=lambda: datetime.now() + timedelta(days=(30 * 365))) # If no expiry, expire after 30 years city = indexes.CharField(model_attr='venue__city', faceted=True, null=True) neighborhood = indexes.CharField(model_attr='venue__neighborhood', faceted=True, null=True) point = indexes.LocationField(model_attr='venue__point', null=True) # We add this for autocomplete. title_auto = indexes.EdgeNgramField(use_template=True) def get_model(self): return Event def prepare_categories(self, obj): return [category.name for category in obj.category.all()] def index_queryset(self, using=None): """Used when the entire index for model is updated.""" return self.get_model().objects.filter(publish=True)
class ProvInfraProjectIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) name = indexes.CharField() province = indexes.CharField(faceted=True) department = indexes.CharField(faceted=True) status = indexes.CharField(faceted=True) status_order = indexes.IntegerField() primary_funding_source = indexes.CharField(faceted=True) estimated_completion_date = indexes.DateField() total_project_cost = indexes.FloatField() latitude = indexes.CharField() longitude = indexes.CharField() url_path = indexes.CharField() def get_model(self): return ProvInfraProject def prepare_name(sef, object): return object.project_snapshots.latest().name def prepare_status(sef, object): return object.project_snapshots.latest().status def prepare_status_order(self, object): return status_order.get(object.project_snapshots.latest().status, 100) def prepare_province(sef, object): return object.project_snapshots.latest().province def prepare_department(sef, object): return object.project_snapshots.latest().department def prepare_primary_funding_source(sef, object): return object.project_snapshots.latest().primary_funding_source def prepare_total_project_cost(sef, object): return object.project_snapshots.latest().total_project_cost def prepare_estimated_completion_date(sef, object): date = object.project_snapshots.latest().estimated_completion_date if date: return date.isoformat() def prepare_latitude(sef, object): return object.project_snapshots.latest().latitude def prepare_longitude(sef, object): return object.project_snapshots.latest().longitude def prepare_url_path(sef, object): return object.get_absolute_url() def should_update(self, instance, **kwargs): return instance.project_snapshots.count() def index_queryset(self, using=None): return ProvInfraProject.objects.annotate( project_snapshots_count=Count("project_snapshots")).filter( project_snapshots_count__gte=1)