diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-01-31 17:06:29 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2019-01-31 17:06:29 +0100 |
commit | 61dee247a1614517c8fb73eb7ada2e33019134b9 (patch) | |
tree | 013b56c339effd0a0540f5cee907986e30fd897a | |
parent | bf3794dcccee7a46ab8bf7177ab119ffb437f6dd (diff) | |
download | Ishtar-61dee247a1614517c8fb73eb7ada2e33019134b9.tar.bz2 Ishtar-61dee247a1614517c8fb73eb7ada2e33019134b9.zip |
Search: manage dynamic query parameters (ex: divisions details)
-rw-r--r-- | archaeological_context_records/models.py | 31 | ||||
-rw-r--r-- | archaeological_files/models.py | 44 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 361 | ||||
-rw-r--r-- | archaeological_finds/models_treatments.py | 40 | ||||
-rw-r--r-- | archaeological_operations/models.py | 191 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 26 | ||||
-rw-r--r-- | ishtar_common/forms.py | 18 | ||||
-rw-r--r-- | ishtar_common/models.py | 159 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 113 |
9 files changed, 535 insertions, 448 deletions
diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index d2faebc1e..d2337db81 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -34,7 +34,7 @@ from ishtar_common.models import Document, GeneralType, \ GeneralRelationType, GeneralRecordRelations, post_delete_record_relation,\ post_save_cache, ValueGetter, BulkUpdatedItem, ExternalIdManager, \ RelationItem, Town, get_current_profile, document_attached_changed, \ - HistoryModel + HistoryModel, SearchAltName from archaeological_operations.models import Operation, Period, Parcel, \ ArchaeologicalSite @@ -321,60 +321,55 @@ class ContextRecord(BulkUpdatedItem, BaseHistorizedItem, 'cr_relation_types': ''} # alternative names of fields for searches ALT_NAMES = { - 'label': ( + 'label': SearchAltName( pgettext_lazy("key for text search", u"id"), 'label__iexact' ), - 'town': ( + 'town': SearchAltName( pgettext_lazy("key for text search", u"town"), 'town__cached_label__iexact' ), - 'operation__year': ( + 'operation__year': SearchAltName( pgettext_lazy("key for text search", u"operation-year"), 'operation__year' ), - 'operation__code_patriarche': ( + 'operation__code_patriarche': SearchAltName( pgettext_lazy("key for text search", u"patriarche"), 'operation__code_patriarche__iexact' ), - 'operation__operation_code': ( + 'operation__operation_code': SearchAltName( pgettext_lazy("key for text search", u"operation-code"), 'operation__operation_code' ), - 'operation__cached_label': ( + 'operation__cached_label': SearchAltName( pgettext_lazy("key for text search", u"operation"), 'operation__cached_label__icontains' ), - 'archaeological_site': ( + 'archaeological_site': SearchAltName( pgettext_lazy("key for text search", u"site"), 'archaeological_site__cached_label__icontains' ), - 'ope_relation_types': ( + 'ope_relation_types': SearchAltName( pgettext_lazy("key for text search", u"operation-relation-type"), 'ope_relation_types' ), - 'datings__period': ( + 'datings__period': SearchAltName( pgettext_lazy("key for text search", u"period"), 'datings__period__label__iexact' ), - 'unit': ( + 'unit': SearchAltName( pgettext_lazy("key for text search", u"unit-type"), 'unit__label__iexact' ), - 'parcel': ( + 'parcel': SearchAltName( pgettext_lazy("key for text search", u"parcel"), 'parcel__cached_label__iexact' ), - 'cr_relation_types': ( + 'cr_relation_types': SearchAltName( pgettext_lazy("key for text search", u"record-relation-type"), 'cr_relation_types' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() PARENT_ONLY_SEARCH_VECTORS = ['operation', "archaeological_site"] BASE_SEARCH_VECTORS = ["cached_label", "label", "location", "town__name", diff --git a/archaeological_files/models.py b/archaeological_files/models.py index 575ec2aef..a9c14cb3a 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -33,7 +33,8 @@ from ishtar_common.utils import cached_label_changed, get_cache, \ from ishtar_common.models import GeneralType, BaseHistorizedItem, \ HistoricalRecords, OwnPerms, Person, Organization, Department, Town, \ Dashboard, DashboardFormItem, ValueGetter, ShortMenuItem, \ - OperationType, get_external_id, post_save_cache, Document, HistoryModel + OperationType, get_external_id, post_save_cache, Document, HistoryModel, \ + SearchAltName from archaeological_operations.models import get_values_town_related, \ ClosedItem @@ -133,85 +134,80 @@ class File(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, # alternative names of fields for searches ALT_NAMES = { - 'year': ( + 'year': SearchAltName( pgettext_lazy("key for text search", u"year"), 'year' ), - 'numeric_reference': ( + 'numeric_reference': SearchAltName( pgettext_lazy("key for text search", u"reference"), 'numeric_reference' ), - 'internal_reference': ( + 'internal_reference': SearchAltName( pgettext_lazy("key for text search", u"other-reference"), 'internal_reference__iexact' ), - 'towns': ( + 'towns': SearchAltName( pgettext_lazy("key for text search", u"town"), 'towns__cached_label__iexact' ), - 'parcel': ( + 'parcel': SearchAltName( pgettext_lazy("key for text search", u"parcel"), 'parcels__cached_label__iexact' ), - 'towns__numero_insee__startswith': ( + 'towns__numero_insee__startswith': SearchAltName( pgettext_lazy("key for text search", u"department"), 'towns__numero_insee__startswith' ), - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'file_type': ( + 'file_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'file_type__label__iexact' ), - 'end_date': ( + 'end_date': SearchAltName( pgettext_lazy("key for text search", u"active"), 'end_date__isnull' ), - 'saisine_type': ( + 'saisine_type': SearchAltName( pgettext_lazy("key for text search", u"saisine-type"), 'saisine_type__label__iexact' ), - 'permit_type': ( + 'permit_type': SearchAltName( pgettext_lazy("key for text search", u"permit-type"), 'permit_type__label__iexact' ), - 'permit_reference': ( + 'permit_reference': SearchAltName( pgettext_lazy("key for text search", u"permit-reference"), 'permit_reference__iexact' ), - 'comment': ( + 'comment': SearchAltName( pgettext_lazy("key for text search", u"comment"), 'comment__iexact' ), - 'in_charge': ( + 'in_charge': SearchAltName( pgettext_lazy("key for text search", u"in-charge"), 'in_charge__cached_label__iexact' ), - 'general_contractor': ( + 'general_contractor': SearchAltName( pgettext_lazy("key for text search", u"general-contractor"), 'general_contractor__cached_label__iexact' ), - 'general_contractor__attached_to': ( + 'general_contractor__attached_to': SearchAltName( pgettext_lazy("key for text search", u"general-contractor-organization"), 'general_contractor__attached_to__cached_label__iexact' ), - 'history_creator': ( + 'history_creator': SearchAltName( pgettext_lazy("key for text search", u"created-by"), 'history_creator__ishtaruser__person__cached_label__iexact' ), - 'history_modifier': ( + 'history_modifier': SearchAltName( pgettext_lazy("key for text search", u"modified-by"), 'history_modifier__ishtaruser__person__cached_label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() POST_PROCESS_REQUEST = { 'towns__numero_insee__startswith': '_get_department_code', diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index 29aeaefcf..ff989fb07 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -41,7 +41,9 @@ from ishtar_common.models import Document, GeneralType, \ HistoricalRecords, OwnPerms, Person, Basket, post_save_cache, \ ValueGetter, get_current_profile, IshtarSiteProfile, PRIVATE_FIELDS, \ SpatialReferenceSystem, BulkUpdatedItem, ExternalIdManager, QuickAction, \ - MainItem, document_attached_changed, HistoryModel + MainItem, document_attached_changed, HistoryModel, DynamicRequest, \ + SearchAltName + from archaeological_operations.models import AdministrativeAct, Operation from archaeological_context_records.models import ContextRecord, Dating @@ -819,181 +821,200 @@ class Find(BulkUpdatedItem, ValueGetter, BaseHistorizedItem, OwnPerms, if key not in EXTRA_REQUEST_KEYS] ) ) + # alternative names of fields for searches ALT_NAMES = { - 'base_finds__cache_short_id': ( - pgettext_lazy("key for text search", u"short-id"), - 'base_finds__cache_short_id__iexact' - ), - 'base_finds__cache_complete_id': ( - pgettext_lazy("key for text search", u"complete-id"), - 'base_finds__cache_complete_id__iexact' - ), - 'label': ( - pgettext_lazy("key for text search", u"free-id"), - 'label__iexact' - ), - 'denomination': ( - pgettext_lazy("key for text search", u"denomination"), - 'denomination__iexact' - ), - 'base_finds__context_record__town': ( - pgettext_lazy("key for text search", u"town"), - 'base_finds__context_record__town__cached_label__iexact' - ), - 'base_finds__context_record__operation__year': ( - pgettext_lazy("key for text search", u"year"), - 'base_finds__context_record__operation__year' - ), - 'base_finds__context_record__operation__operation_code': ( - pgettext_lazy("key for text search", u"operation-code"), - 'base_finds__context_record__operation__operation_code' - ), - 'base_finds__context_record__operation__code_patriarche': ( - pgettext_lazy("key for text search", u"code-patriarche"), - 'base_finds__context_record__operation__code_patriarche__iexact' - ), - 'base_finds__context_record__operation__operation_type': ( - pgettext_lazy("key for text search", u"operation-type"), - 'base_finds__context_record__operation__operation_type' - '__label__iexact' - ), - 'base_finds__context_record__town__areas': ( - pgettext_lazy("key for text search", u"area"), - 'base_finds__context_record__town__areas__label__iexact', - ), - 'archaeological_sites': ( - pgettext_lazy("key for text search", u"site"), - 'base_finds__context_record__operation__archaeological_sites__' - 'cached_label__icontains', - ), - 'archaeological_sites_context_record': ( - pgettext_lazy("key for text search", u"context-record-site"), - 'base_finds__context_record__archaeological_site__' - 'cached_label__icontains', - ), - 'base_finds__context_record': ( - pgettext_lazy("key for text search", u"context-record"), - 'base_finds__context_record__cached_label__icontains', - ), - 'ope_relation_types': ( - pgettext_lazy("key for text search", u"operation-relation-type"), - 'ope_relation_types' - ), - 'cr_relation_types': ( - pgettext_lazy("key for text search", u"context-record-relation-type"), - 'cr_relation_types' - ), - 'datings__period': ( - pgettext_lazy("key for text search", u"period"), - 'datings__period__label__iexact', - ), - 'material_types': ( - pgettext_lazy("key for text search", u"material"), - 'material_types__label__iexact', - ), - 'object_types': ( - pgettext_lazy("key for text search", u"object-type"), - 'object_types__label__iexact', - ), - 'preservation_to_considers': ( - pgettext_lazy("key for text search", u"preservation"), - 'preservation_to_considers__label__iexact', - ), - 'conservatory_state': ( - pgettext_lazy("key for text search", u"conservatory"), - 'conservatory_state__label__iexact', - ), - 'integrities': ( - pgettext_lazy("key for text search", u"integrity"), - 'integrities__label__iexact', - ), - 'remarkabilities': ( - pgettext_lazy("key for text search", u"remarkability"), - 'remarkabilities__label__iexact', - ), - 'base_finds__find__description': ( - pgettext_lazy("key for text search", u"description"), - 'base_finds__find__description__iexact', - ), - 'base_finds__batch': ( - pgettext_lazy("key for text search", u"batch"), - 'base_finds__batch__label__iexact', - ), - 'checked_type': ( - pgettext_lazy("key for text search", u"checked"), - 'checked_type__label__iexact', - ), - 'documents__image__isnull': ( - pgettext_lazy("key for text search", u"has-image"), - 'documents__image__isnull', - ), - 'container_ref__location': ( - pgettext_lazy("key for text search", u"location"), - 'container_ref__location__name__iexact', - ), - 'container_ref__responsible': ( - pgettext_lazy("key for text search", u"warehouse"), - 'container_ref__responsible__name__iexact', - ), - 'container_ref__index': ( - pgettext_lazy("key for text search", u"container-index"), - 'container_ref__index', - ), - 'container_ref__reference': ( - pgettext_lazy("key for text search", u"container-ref"), - 'container_ref__reference__iexact', - ), - 'container__location': ( - pgettext_lazy("key for text search", u"current-location"), - 'container__location__name__iexact', - ), - 'container__responsible': ( - pgettext_lazy("key for text search", u"current-warehouse"), - 'container__responsible__name__iexact', - ), - 'container__index': ( - pgettext_lazy("key for text search", u"current-container-index"), - 'container__index', - ), - 'container__reference': ( - pgettext_lazy("key for text search", u"current-container-ref"), - 'container__reference__iexact', - ), - 'basket': ( - pgettext_lazy("key for text search", u"basket"), - 'basket__label__iexact' - ), - 'base_finds__context_record__operation__cached_label': ( - pgettext_lazy("key for text search", u"operation"), - 'base_finds__context_record__operation__cached_label__icontains' - ), - 'history_modifier': ( - pgettext_lazy("key for text search", u"last-modified-by"), - 'history_modifier__ishtaruser__person__cached_label__icontains' - ), - 'modified_since': ( - pgettext_lazy("key for text search", u"modified-since"), - 'last_modified__gte' + 'base_finds__cache_short_id': + SearchAltName(pgettext_lazy("key for text search", u"short-id"), + 'base_finds__cache_short_id__iexact'), + 'base_finds__cache_complete_id': + SearchAltName(pgettext_lazy("key for text search", u"complete-id"), + 'base_finds__cache_complete_id__iexact'), + 'label': + SearchAltName(pgettext_lazy("key for text search", u"free-id"), + 'label__iexact'), + 'denomination': + SearchAltName(pgettext_lazy("key for text search", u"denomination"), + 'denomination__iexact'), + 'base_finds__context_record__town': + SearchAltName( + pgettext_lazy("key for text search", u"town"), + 'base_finds__context_record__town__cached_label__iexact'), + 'base_finds__context_record__operation__year': + SearchAltName(pgettext_lazy("key for text search", u"year"), + 'base_finds__context_record__operation__year'), + 'base_finds__context_record__operation__operation_code': + SearchAltName( + pgettext_lazy("key for text search", u"operation-code"), + 'base_finds__context_record__operation__operation_code'), + 'base_finds__context_record__operation__code_patriarche': + SearchAltName( + pgettext_lazy("key for text search", u"code-patriarche"), + 'base_finds__context_record__operation__code_patriarche__iexact' + ), + 'base_finds__context_record__operation__operation_type': + SearchAltName( + pgettext_lazy("key for text search", u"operation-type"), + 'base_finds__context_record__operation__operation_type' + '__label__iexact'), + 'base_finds__context_record__town__areas': + SearchAltName( + pgettext_lazy("key for text search", u"area"), + 'base_finds__context_record__town__areas__label__iexact'), + 'archaeological_sites': + SearchAltName( + pgettext_lazy("key for text search", u"site"), + 'base_finds__context_record__operation__archaeological_sites__' + 'cached_label__icontains'), + 'archaeological_sites_context_record': + SearchAltName( + pgettext_lazy("key for text search", u"context-record-site"), + 'base_finds__context_record__archaeological_site__' + 'cached_label__icontains'), + 'base_finds__context_record': + SearchAltName( + pgettext_lazy("key for text search", u"context-record"), + 'base_finds__context_record__cached_label__icontains'), + 'ope_relation_types': + SearchAltName( + pgettext_lazy("key for text search", + u"operation-relation-type"), + 'ope_relation_types'), + 'cr_relation_types': + SearchAltName( + pgettext_lazy("key for text search", + u"context-record-relation-type"), + 'cr_relation_types'), + 'datings__period': + SearchAltName( + pgettext_lazy("key for text search", u"period"), + 'datings__period__label__iexact'), + 'material_types': + SearchAltName( + pgettext_lazy("key for text search", u"material"), + 'material_types__label__iexact'), + 'object_types': + SearchAltName( + pgettext_lazy("key for text search", u"object-type"), + 'object_types__label__iexact'), + 'preservation_to_considers': + SearchAltName( + pgettext_lazy("key for text search", u"preservation"), + 'preservation_to_considers__label__iexact'), + 'conservatory_state': + SearchAltName( + pgettext_lazy("key for text search", u"conservatory"), + 'conservatory_state__label__iexact'), + 'integrities': + SearchAltName( + pgettext_lazy("key for text search", u"integrity"), + 'integrities__label__iexact'), + 'remarkabilities': + SearchAltName( + pgettext_lazy("key for text search", u"remarkability"), + 'remarkabilities__label__iexact'), + 'base_finds__find__description': + SearchAltName( + pgettext_lazy("key for text search", u"description"), + 'base_finds__find__description__iexact'), + 'base_finds__batch': + SearchAltName( + pgettext_lazy("key for text search", u"batch"), + 'base_finds__batch__label__iexact'), + 'checked_type': + SearchAltName( + pgettext_lazy("key for text search", u"checked"), + 'checked_type__label__iexact'), + 'documents__image__isnull': + SearchAltName( + pgettext_lazy("key for text search", u"has-image"), + 'documents__image__isnull'), + 'container_ref__location': + SearchAltName( + pgettext_lazy("key for text search", u"location"), + 'container_ref__location__name__iexact'), + 'container_ref__responsible': + SearchAltName( + pgettext_lazy("key for text search", u"warehouse"), + 'container_ref__responsible__name__iexact'), + 'container_ref__index': + SearchAltName( + pgettext_lazy("key for text search", u"container-index"), + 'container_ref__index'), + 'container_ref__reference': + SearchAltName( + pgettext_lazy("key for text search", u"container-ref"), + 'container_ref__reference__iexact'), + 'container__location': + SearchAltName( + pgettext_lazy("key for text search", u"current-location"), + 'container__location__name__iexact'), + 'container__responsible': + SearchAltName( + pgettext_lazy("key for text search", u"current-warehouse"), + 'container__responsible__name__iexact'), + 'container__index': + SearchAltName( + pgettext_lazy("key for text search", + u"current-container-index"), + 'container__index'), + 'container__reference': + SearchAltName( + pgettext_lazy("key for text search", u"current-container-ref"), + 'container__reference__iexact'), + 'basket': + SearchAltName( + pgettext_lazy("key for text search", u"basket"), + 'basket__label__iexact'), + 'base_finds__context_record__operation__cached_label': + SearchAltName( + pgettext_lazy("key for text search", u"operation"), + 'base_finds__context_record__operation__cached_label__icontains' + ), + 'history_modifier': + SearchAltName( + pgettext_lazy("key for text search", u"last-modified-by"), + 'history_modifier__ishtaruser__person__cached_label__icontains' + ), + 'modified_since': + SearchAltName( + pgettext_lazy("key for text search", u"modified-since"), + 'last_modified__gte'), + 'history_creator': + SearchAltName( + pgettext_lazy("key for text search", u"created-by"), + 'history_creator__ishtaruser__person__cached_label__iexact' ), - 'history_creator': ( - pgettext_lazy("key for text search", u"created-by"), - 'history_creator__ishtaruser__person__cached_label__iexact' + 'loan': + SearchAltName( + pgettext_lazy("key for text search", u"loan"), query_loan), + 'treatments_file_end_date': + SearchAltName( + pgettext_lazy("key for text search", + u"treatment-end-date-before"), + 'treatments__file__end_date__lte'), + } + + DYNAMIC_REQUESTS = { + 'current_division': DynamicRequest( + label=_(u"Division current -"), + app_name='archaeological_warehouse', model_name='WarehouseDivision', + form_key='current_division', + search_key=pgettext_lazy("key for text search", + 'current-division'), + type_query='container__division__division__division__txt_idx', + search_query='container__division__reference__iexact' ), - 'loan': ( - pgettext_lazy("key for text search", u"loan"), - query_loan + 'reference_division': DynamicRequest( + label=_(u"Division reference -"), + app_name='archaeological_warehouse', model_name='WarehouseDivision', + form_key='reference_division', + search_key=pgettext_lazy("key for text search", + 'reference-division'), + type_query='container_ref__division__division__division__txt_idx', + search_query='container_ref__division__reference__iexact' ), - 'treatments_file_end_date': ( - pgettext_lazy("key for text search", u"treatment-end-date-before"), - 'treatments__file__end_date__lte' - ) } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() PARENT_SEARCH_VECTORS = ['base_finds'] BASE_SEARCH_VECTORS = [ diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index a8c48a3ad..7d9b8ebb6 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -37,7 +37,7 @@ from ishtar_common.models import Document, GeneralType, \ ImageModel, BaseHistorizedItem, OwnPerms, HistoricalRecords, Person, \ Organization, ValueGetter, post_save_cache, ShortMenuItem, \ DashboardFormItem, ExternalIdManager, document_attached_changed, \ - HistoryModel + HistoryModel, SearchAltName from ishtar_common.utils import cached_label_changed, get_current_year, \ update_data, m2m_historization_changed @@ -92,36 +92,31 @@ class Treatment(DashboardFormItem, ValueGetter, BaseHistorizedItem, # alternative names of fields for searches ALT_NAMES = { - 'label': ( + 'label': SearchAltName( pgettext_lazy("key for text search", u"label"), 'label__iexact' ), - 'other_reference': ( + 'other_reference': SearchAltName( pgettext_lazy("key for text search", u"other-reference"), 'other_reference__iexact' ), - 'year': ( + 'year': SearchAltName( pgettext_lazy("key for text search", u"year"), 'year' ), - 'index': ( + 'index': SearchAltName( pgettext_lazy("key for text search", u"index"), 'index' ), - 'documents__image__isnull': ( + 'documents__image__isnull': SearchAltName( pgettext_lazy("key for text search", u"has-image"), 'documents__image__isnull' ), - 'treatment_types': ( + 'treatment_types': SearchAltName( pgettext_lazy("key for text search", u"type"), 'treatment_types__label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() HISTORICAL_M2M = [ 'treatment_types', ] @@ -871,44 +866,39 @@ class TreatmentFile(DashboardFormItem, ClosedItem, BaseHistorizedItem, EXTRA_REQUEST_KEYS = {} # alternative names of fields for searches ALT_NAMES = { - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'internal_reference': ( + 'internal_reference': SearchAltName( pgettext_lazy("key for text search", u"reference"), 'internal_reference__iexact' ), - 'year': ( + 'year': SearchAltName( pgettext_lazy("key for text search", u"year"), 'year' ), - 'index': ( + 'index': SearchAltName( pgettext_lazy("key for text search", u"index"), 'index' ), - 'type': ( + 'type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'type__label__iexact' ), - 'in_charge': ( + 'in_charge': SearchAltName( pgettext_lazy("key for text search", u"in-charge"), 'in_charge__cached_label__iexact' ), - 'applicant': ( + 'applicant': SearchAltName( pgettext_lazy("key for text search", u"applicant"), 'applicant__cached_label__iexact' ), - 'applicant_organisation': ( + 'applicant_organisation': SearchAltName( pgettext_lazy("key for text search", u"applicant-organisation"), 'applicant_organisation__cached_label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() # fields year = models.IntegerField(_(u"Year"), default=get_current_year) diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 7d194074d..e711def95 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -37,7 +37,7 @@ from ishtar_common.models import BaseHistorizedItem, Dashboard, \ OperationType, Organization, OwnPerms, Person, PersonType, \ post_delete_record_relation, post_save_cache, RelationItem, \ ShortMenuItem, SourceType, Town, ValueGetter, get_current_profile, \ - document_attached_changed, HistoryModel + document_attached_changed, HistoryModel, SearchAltName from ishtar_common.utils import cached_label_changed, \ force_cached_label_changed, mode, m2m_historization_changed @@ -135,81 +135,76 @@ class ArchaeologicalSite(BaseHistorizedItem, OwnPerms, ValueGetter, # alternative names of fields for searches ALT_NAMES = { - 'reference': ( + 'reference': SearchAltName( pgettext_lazy("key for text search", u"reference"), 'reference__iexact' ), - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'periods': ( + 'periods': SearchAltName( pgettext_lazy("key for text search", u"period"), 'periods__label__iexact' ), - 'remains': ( + 'remains': SearchAltName( pgettext_lazy("key for text search", u"remain"), 'remains__label__iexact' ), - 'towns': ( + 'towns': SearchAltName( pgettext_lazy("key for text search", u"town"), 'towns__cached_label__iexact' ), - 'comment': ( + 'comment': SearchAltName( pgettext_lazy("key for text search", u"comment"), 'comment__iexact' ), - 'locality_ngi': ( + 'locality_ngi': SearchAltName( pgettext_lazy("key for text search", u"locality-ngi"), 'locality_ngi__iexact' ), - 'locality_cadastral': ( + 'locality_cadastral': SearchAltName( pgettext_lazy("key for text search", u"locality-cadastral"), 'locality_cadastral__iexact' ), - 'shipwreck_name': ( + 'shipwreck_name': SearchAltName( pgettext_lazy("key for text search", u"shipwreck-name"), 'shipwreck_name__iexact' ), - 'oceanographic_service_localisation': ( + 'oceanographic_service_localisation': SearchAltName( pgettext_lazy("key for text search", u"oceanographic-service-localisation"), 'oceanographic_service_localisation__iexact' ), - 'shipwreck_code': ( + 'shipwreck_code': SearchAltName( pgettext_lazy("key for text search", u"shipwreck-code"), 'shipwreck_code__iexact' ), - 'sinking_date': ( + 'sinking_date': SearchAltName( pgettext_lazy("key for text search", u"sinking-date"), 'sinking_date' ), - 'discovery_area': ( + 'discovery_area': SearchAltName( pgettext_lazy("key for text search", u"discovery-area"), 'discovery_area__iexact' ), - 'operation': ( + 'operation': SearchAltName( pgettext_lazy("key for text search", u"operation"), 'operations__cached_label__icontains' ), - 'top_operation': ( + 'top_operation': SearchAltName( pgettext_lazy("key for text search", u"top-operation"), 'top_operation__cached_label__icontains' ), - 'drassm_number': ( + 'drassm_number': SearchAltName( pgettext_lazy("key for text search", u"numero-drassm"), 'drassm_number__iexact' ), - 'affmar_number': ( + 'affmar_number': SearchAltName( pgettext_lazy("key for text search", u"numero-affmar"), 'affmar_number__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() UP_MODEL_QUERY = { "operation": (pgettext_lazy("key for text search", u"operation"), @@ -592,160 +587,155 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, # alternative names of fields for searches ALT_NAMES = { - 'year': ( + 'year': SearchAltName( pgettext_lazy("key for text search", u"year"), 'year' ), - 'operation_code': ( + 'operation_code': SearchAltName( pgettext_lazy("key for text search", u"operation-code"), 'operation_code' ), - 'code_patriarche': ( + 'code_patriarche': SearchAltName( pgettext_lazy("key for text search", u"patriarche"), 'code_patriarche__iexact' ), - 'towns': ( + 'towns': SearchAltName( pgettext_lazy("key for text search", u"town"), 'towns__cached_label__iexact' ), - 'parcel': ( + 'parcel': SearchAltName( pgettext_lazy("key for text search", u"parcel"), 'parcels__cached_label__iexact' ), - 'towns__numero_insee__startswith': ( + 'towns__numero_insee__startswith': SearchAltName( pgettext_lazy("key for text search", u"department"), 'towns__numero_insee__startswith' ), - 'common_name': ( + 'common_name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'common_name__iexact' ), - 'address': ( + 'address': SearchAltName( pgettext_lazy("key for text search", u"address"), 'address__iexact' ), - 'operation_type': ( + 'operation_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'operation_type__label__iexact' ), - 'end_date': ( + 'end_date': SearchAltName( pgettext_lazy("key for text search", u"is-open"), 'end_date__isnull' ), - 'in_charge': ( + 'in_charge': SearchAltName( pgettext_lazy("key for text search", u"in-charge"), 'in_charge__cached_label__iexact' ), - 'scientist': ( + 'scientist': SearchAltName( pgettext_lazy("key for text search", u"scientist"), 'scientist__cached_label__iexact' ), - 'operator': ( + 'operator': SearchAltName( pgettext_lazy("key for text search", u"operator"), 'operator__cached_label__iexact' ), - 'remains': ( + 'remains': SearchAltName( pgettext_lazy("key for text search", u"remain"), 'remains__label__iexact' ), - 'periods': ( + 'periods': SearchAltName( pgettext_lazy("key for text search", u"period"), 'periods__label__iexact' ), - 'start_before': ( + 'start_before': SearchAltName( pgettext_lazy("key for text search", u"start-before"), 'start_date__lte' ), - 'start_after': ( + 'start_after': SearchAltName( pgettext_lazy("key for text search", u"start-after"), 'start_date__gte' ), - 'end_before': ( + 'end_before': SearchAltName( pgettext_lazy("key for text search", u"end-before"), 'excavation_end_date__lte' ), - 'end_after': ( + 'end_after': SearchAltName( pgettext_lazy("key for text search", u"end-after"), 'excavation_end_date__gte' ), - 'relation_types': ( + 'relation_types': SearchAltName( pgettext_lazy("key for text search", u"relation-types"), 'relation_types' ), - 'comment': ( + 'comment': SearchAltName( pgettext_lazy("key for text search", u"comment"), 'comment__iexact' ), - 'abstract': ( + 'abstract': SearchAltName( pgettext_lazy("key for text search", u"abstract"), 'abstract__iexact' ), - 'scientific_documentation_comment': ( + 'scientific_documentation_comment': SearchAltName( pgettext_lazy("key for text search", u"scientific-documentation-comment"), 'scientific_documentation_comment__iexact' ), - 'record_quality_type': ( + 'record_quality_type': SearchAltName( pgettext_lazy("key for text search", u"record-quality"), 'record_quality_type__label__iexact' ), - 'report_processing': ( + 'report_processing': SearchAltName( pgettext_lazy("key for text search", u"report-processing"), 'report_processing__label__iexact' ), - 'virtual_operation': ( + 'virtual_operation': SearchAltName( pgettext_lazy("key for text search", u"virtual-operation"), 'virtual_operation' ), - 'archaeological_sites': ( + 'archaeological_sites': SearchAltName( pgettext_lazy("key for text search", u"site"), 'archaeological_sites__cached_label__icontains' ), - 'history_creator': ( + 'history_creator': SearchAltName( pgettext_lazy("key for text search", u"created-by"), 'history_creator__ishtaruser__person__cached_label__iexact' ), - 'history_modifier': ( + 'history_modifier': SearchAltName( pgettext_lazy("key for text search", u"modified-by"), 'history_modifier__ishtaruser__person__cached_label__iexact' ), - 'documentation_received': ( + 'documentation_received': SearchAltName( pgettext_lazy("key for text search", u"documentation-received"), 'documentation_received' ), - 'documentation_deadline_before': ( + 'documentation_deadline_before': SearchAltName( pgettext_lazy("key for text search", u"documentation-deadline-before"), 'documentation_deadline__lte' ), - 'documentation_deadline_after': ( + 'documentation_deadline_after': SearchAltName( pgettext_lazy("key for text search", u"documentation-deadline-after"), 'documentation_deadline__gte' ), - 'finds_received': ( + 'finds_received': SearchAltName( pgettext_lazy("key for text search", u"finds-received"), 'finds_received' ), - 'finds_deadline_before': ( + 'finds_deadline_before': SearchAltName( pgettext_lazy("key for text search", u"finds-deadline-before"), 'finds_deadline__lte' ), - 'finds_deadline_after': ( + 'finds_deadline_after': SearchAltName( pgettext_lazy("key for text search", u"finds-deadline-after"), 'finds_deadline__gte' ), - 'drassm_code': ( + 'drassm_code': SearchAltName( pgettext_lazy("key for text search", u"code-drassm"), 'drassm_code__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() UP_MODEL_QUERY = { "site": (pgettext_lazy("key for text search", u"site"), @@ -1602,153 +1592,148 @@ class AdministrativeAct(BaseHistorizedItem, OwnPerms, ValueGetter): 'treatment'] # alternative names of fields for searches ALT_NAMES = { - 'year': ( + 'year': SearchAltName( pgettext_lazy("key for text search", u"year"), 'signature_date__year' ), - 'index': ( + 'index': SearchAltName( pgettext_lazy("key for text search", u"index"), 'index' ), - 'ref_sra': ( + 'ref_sra': SearchAltName( pgettext_lazy("key for text search", u"other-ref"), 'ref_sra__iexact' ), - 'operation__code_patriarche': ( + 'operation__code_patriarche': SearchAltName( pgettext_lazy("key for text search", u"patriarche"), 'operation__code_patriarche' ), - 'act_type': ( + 'act_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'act_type__label__iexact' ), - 'indexed': ( + 'indexed': SearchAltName( pgettext_lazy("key for text search", u"indexed"), 'index__isnull' ), - 'operation__towns': ( + 'operation__towns': SearchAltName( pgettext_lazy("key for text search", u"operation-town"), 'operation__towns__cached_label__iexact' ), - 'associated_file__towns': ( + 'associated_file__towns': SearchAltName( pgettext_lazy("key for text search", u"file-town"), 'associated_file__towns__cached_label__iexact' ), - 'parcel': ( + 'parcel': SearchAltName( pgettext_lazy("key for text search", u"parcel"), ('associated_file__parcels__cached_label__iexact', 'operation__parcels__cached_label__iexact', 'operation__associated_file__parcels__cached_label__iexact'), ), - 'operation__towns__numero_insee__startswith': ( + 'operation__towns__numero_insee__startswith': SearchAltName( pgettext_lazy("key for text search", u"operation-department"), 'operation__towns__numero_insee__startswith' ), - 'associated_file__towns__numero_insee__startswith': ( + 'associated_file__towns__numero_insee__startswith': SearchAltName( pgettext_lazy("key for text search", u"file-department"), 'associated_file__towns__numero_insee__startswith' ), - 'act_object': ( + 'act_object': SearchAltName( pgettext_lazy("key for text search", u"object"), 'act_object__icontains' ), - 'history_creator': ( + 'history_creator': SearchAltName( pgettext_lazy("key for text search", u"created-by"), 'history_creator__ishtaruser__person__cached_label__iexact' ), - 'history_modifier': ( + 'history_modifier': SearchAltName( pgettext_lazy("key for text search", u"modified-by"), 'history_modifier__ishtaruser__person__cached_label__iexact' ), - 'signature_date_before': ( + 'signature_date_before': SearchAltName( pgettext_lazy("key for text search", u"signature-before"), 'signature_date__lte' ), - 'signature_date_after': ( + 'signature_date_after': SearchAltName( pgettext_lazy("key for text search", u"signature-after"), 'signature_date__gte' ), - 'associated_file__name': ( + 'associated_file__name': SearchAltName( pgettext_lazy("key for text search", u"file-name"), 'associated_file__name__icontains' ), - 'associated_file__general_contractor': ( + 'associated_file__general_contractor': SearchAltName( pgettext_lazy("key for text search", u"general-contractor"), 'associated_file__general_contractor__cached_label__iexact' ), - 'associated_file__general_contractor__attached_to': ( + 'associated_file__general_contractor__attached_to': SearchAltName( pgettext_lazy("key for text search", u"general-contractor-organization"), 'associated_file__general_contractor__attached_to' '__cached_label__iexact' ), - 'associated_file__numeric_reference': ( + 'associated_file__numeric_reference': SearchAltName( pgettext_lazy("key for text search", u"file-reference"), 'associated_file__numeric_reference' ), - 'associated_file__year': ( + 'associated_file__year': SearchAltName( pgettext_lazy("key for text search", u"file-year"), 'associated_file__year' ), - 'associated_file__internal_reference': ( + 'associated_file__internal_reference': SearchAltName( pgettext_lazy("key for text search", u"file-other-reference"), 'associated_file__internal_reference__iexact' ), - 'associated_file__in_charge': ( + 'associated_file__in_charge': SearchAltName( pgettext_lazy("key for text search", u"file-in-charge"), 'associated_file__in_charge__cached_label__iexact' ), - 'associated_file__permit_reference': ( + 'associated_file__permit_reference': SearchAltName( pgettext_lazy("key for text search", u"file-permit-reference"), 'associated_file__permit_reference__iexact' ), - 'treatment__name': ( + 'treatment__name': SearchAltName( pgettext_lazy("key for text search", u"treatment-name"), 'treatment__label__icontains' ), - 'treatment__other_reference': ( + 'treatment__other_reference': SearchAltName( pgettext_lazy("key for text search", u"treatment-reference"), 'treatment__other_reference__icontains' ), - 'treatment__year': ( + 'treatment__year': SearchAltName( pgettext_lazy("key for text search", u"treatment-year"), 'treatment__year' ), - 'treatment__index': ( + 'treatment__index': SearchAltName( pgettext_lazy("key for text search", u"treatment-index"), 'treatment__index' ), - 'treatment__treatment_types': ( + 'treatment__treatment_types': SearchAltName( pgettext_lazy("key for text search", u"treatment-type"), 'treatment__treatment_types__label__iexact' ), - 'treatment_file__name': ( + 'treatment_file__name': SearchAltName( pgettext_lazy("key for text search", u"treatment-file-name"), 'treatment_file__name__icontains' ), - 'treatment_file__internal_reference': ( + 'treatment_file__internal_reference': SearchAltName( pgettext_lazy("key for text search", u"treatment-file-reference"), 'treatment_file__internal_reference__icontains' ), - 'treatment_file__year': ( + 'treatment_file__year': SearchAltName( pgettext_lazy("key for text search", u"treatment-file-year"), 'treatment_file__year' ), - 'treatment_file__index': ( + 'treatment_file__index': SearchAltName( pgettext_lazy("key for text search", u"treatment-file-index"), 'treatment_file__index' ), - 'treatment_file__type': ( + 'treatment_file__type': SearchAltName( pgettext_lazy("key for text search", u"treatment-file-type"), 'treatment_file__type__label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() UP_MODEL_QUERY = {} POST_PROCESS_REQUEST = { diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 65b5728f9..34ccba88d 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -32,7 +32,7 @@ from ishtar_common.data_importer import post_importer_action from ishtar_common.models import Document, GeneralType, get_external_id, \ LightHistorizedItem, OwnPerms, Address, Person, post_save_cache, \ ImageModel, DashboardFormItem, ExternalIdManager, ShortMenuItem, \ - document_attached_changed + document_attached_changed, SearchAltName from ishtar_common.utils import cached_label_changed @@ -58,20 +58,16 @@ class Warehouse(Address, DashboardFormItem, OwnPerms, EXTRA_REQUEST_KEYS = {} # alternative names of fields for searches ALT_NAMES = { - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'warehouse_type': ( + 'warehouse_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'warehouse_type__label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() + objects = ExternalIdManager() name = models.CharField(_(u"Name"), max_length=200) @@ -355,28 +351,24 @@ class Container(LightHistorizedItem, ImageModel, OwnPerms): # alternative names of fields for searches ALT_NAMES = { - 'location_name': ( + 'location_name': SearchAltName( pgettext_lazy("key for text search", u"location"), 'location__name__iexact' ), - 'responsible_name': ( + 'responsible_name': SearchAltName( pgettext_lazy("key for text search", u"responsible-warehouse"), 'responsible__name__iexact' ), - 'container_type': ( + 'container_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'container_type__label__iexact' ), - 'reference': ( + 'reference': SearchAltName( pgettext_lazy("key for text search", u"reference"), 'reference__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() + objects = ExternalIdManager() # fields diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 2a072aade..93c6cd8ed 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -569,17 +569,25 @@ class IshtarForm(forms.Form, BSForm): class TableSelect(IshtarForm): def __init__(self, *args, **kwargs): super(TableSelect, self).__init__(*args, **kwargs) - ALT_NAMES = {} - if hasattr(self, '_model') and hasattr(self._model, "ALT_NAMES"): - ALT_NAMES = self._model.ALT_NAMES + alt_names = {} + if hasattr(self, '_model'): + if hasattr(self._model, "get_alt_names"): + alt_names = self._model.get_alt_names() + + for k_dyn in self._model.DYNAMIC_REQUESTS: + dyn = self._model.DYNAMIC_REQUESTS[k_dyn] + fields = dyn.get_form_fields() + for k in fields: + self.fields[k] = fields[k] + for k in self.fields: self.fields[k].required = False # no field is required for search cls = 'form-control' if k == 'search_vector': cls += " search-vector" self.fields[k].widget.attrs['class'] = cls - if k in ALT_NAMES: - self.fields[k].alt_name = ALT_NAMES[k][0] + if k in alt_names: + self.fields[k].alt_name = alt_names[k].search_key else: self.fields[k].alt_name = k key = self.fields.keys()[0] diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 12f7dc47b..7f5857037 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -33,9 +33,10 @@ import tempfile import time from cStringIO import StringIO from subprocess import Popen, PIPE - - from PIL import Image + +from django import forms +from django.apps import apps from django.conf import settings from django.contrib.auth.models import User, Group from django.contrib.contenttypes.fields import GenericForeignKey @@ -1240,9 +1241,62 @@ class Imported(models.Model): abstract = True +class SearchAltName(object): + def __init__(self, search_key, search_query, extra_query=None, + distinct_query=False): + self.search_key = search_key + self.search_query = search_query + self.extra_query = extra_query or {} + self.distinct_query = distinct_query + + +class DynamicRequest(object): + def __init__(self, label, app_name, model_name, form_key, search_key, + type_query, search_query): + self.label = label + self.form_key = form_key + self.search_key = search_key + self.app_name = app_name + self.model_name = model_name + self.type_query = type_query + self.search_query = search_query + + def get_all_types(self): + model = apps.get_app_config(self.app_name).get_model(self.model_name) + return model.objects.filter(available=True) + + def get_form_fields(self): + fields = {} + for item in self.get_all_types().all(): + fields[self.form_key + "-" + item.txt_idx] = forms.CharField( + label=unicode(self.label) + u" " + unicode(item), + required=False + ) + return fields + + def get_extra_query(self, slug): + return { + self.type_query: slug + } + + def get_alt_names(self): + alt_names = {} + for item in self.get_all_types().all(): + alt_names[self.form_key + "-" + item.txt_idx] = SearchAltName( + self.search_key + "-" + item.txt_idx, self.search_query, + self.get_extra_query(item.txt_idx), distinct_query=True + ) + return alt_names + + class FullSearch(models.Model): search_vector = SearchVectorField(_("Search vector"), blank=True, null=True, help_text=_("Auto filled at save")) + + EXTRA_REQUEST_KEYS = {} + DYNAMIC_REQUESTS = {} + ALT_NAMES = {} + BASE_SEARCH_VECTORS = [] PROPERTY_SEARCH_VECTORS = [] INT_SEARCH_VECTORS = [] @@ -1264,6 +1318,23 @@ class FullSearch(models.Model): if issubclass(rel_model, (GeneralType, HierarchicalType)): yield k + @classmethod + def get_alt_names(cls): + alt_names = cls.ALT_NAMES.copy() + for dr_k in cls.DYNAMIC_REQUESTS: + alt_names.update(cls.DYNAMIC_REQUESTS[dr_k].get_alt_names()) + return alt_names + + @classmethod + def get_query_parameters(cls): + query_parameters = {} + for v in cls.get_alt_names().values(): + for language_code, language_lbl in settings.LANGUAGES: + activate(language_code) + query_parameters[unicode(v.search_key)] = v + deactivate() + return query_parameters + def update_search_vector(self, save=True, exclude_parent=False): """ Update the search vector @@ -2692,7 +2763,6 @@ class Department(models.Model): return res - class Address(BaseHistorizedItem): address = models.TextField(_(u"Address"), null=True, blank=True) address_complement = models.TextField(_(u"Address complement"), null=True, @@ -2880,20 +2950,16 @@ class Organization(Address, Merge, OwnPerms, ValueGetter): # alternative names of fields for searches ALT_NAMES = { - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'organization_type': ( + 'organization_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'organization_type__label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() + objects = OrganizationManager() # fields @@ -3029,36 +3095,32 @@ class Person(Address, Merge, OwnPerms, ValueGetter): # alternative names of fields for searches ALT_NAMES = { - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'name__iexact' ), - 'surname': ( + 'surname': SearchAltName( pgettext_lazy("key for text search", u"surname"), 'surname__iexact' ), - 'email': ( + 'email': SearchAltName( pgettext_lazy("key for text search", u"email"), 'email__iexact' ), - 'person_types': ( + 'person_types': SearchAltName( pgettext_lazy("key for text search", u"type"), 'person_types__label__iexact' ), - 'attached_to': ( + 'attached_to': SearchAltName( pgettext_lazy("key for text search", u"organization"), 'attached_to__cached_label__iexact' ), - 'ishtaruser__isnull': ( + 'ishtaruser__isnull': SearchAltName( pgettext_lazy("key for text search", u"has-account"), 'ishtaruser__isnull' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() + objects = PersonManager() # fields @@ -3433,36 +3495,31 @@ class IshtarUser(FullSearch): # alternative names of fields for searches ALT_NAMES = { - 'username': ( + 'username': SearchAltName( pgettext_lazy("key for text search", u"username"), 'user_ptr__username__iexact' ), - 'name': ( + 'name': SearchAltName( pgettext_lazy("key for text search", u"name"), 'person__name__iexact' ), - 'surname': ( + 'surname': SearchAltName( pgettext_lazy("key for text search", u"surname"), 'person__surname__iexact' ), - 'email': ( + 'email': SearchAltName( pgettext_lazy("key for text search", u"email"), 'person__email__iexact' ), - 'person_types': ( + 'person_types': SearchAltName( pgettext_lazy("key for text search", u"type"), 'person__person_types__label__iexact' ), - 'attached_to': ( + 'attached_to': SearchAltName( pgettext_lazy("key for text search", u"organization"), 'person__attached_to__cached_label__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() # fields user_ptr = models.OneToOneField(User, primary_key=True, @@ -3807,76 +3864,72 @@ class Document(BaseHistorizedItem, OwnPerms, ImageModel): # alternative names of fields for searches ALT_NAMES = { - 'authors': ( + 'authors': SearchAltName( pgettext_lazy("key for text search", u"author"), 'authors__cached_label__iexact' ), - 'title': ( + 'title': SearchAltName( pgettext_lazy("key for text search", u"title"), 'title__iexact' ), - 'source_type': ( + 'source_type': SearchAltName( pgettext_lazy("key for text search", u"type"), 'source_type__label__iexact' ), - 'reference': ( + 'reference': SearchAltName( pgettext_lazy("key for text search", u"reference"), 'reference__iexact' ), - 'internal_reference': ( + 'internal_reference': SearchAltName( pgettext_lazy("key for text search", u"internal-reference"), 'internal_reference__iexact' ), - 'description': ( + 'description': SearchAltName( pgettext_lazy("key for text search", u"description"), 'description__iexact' ), - 'comment': ( + 'comment': SearchAltName( pgettext_lazy("key for text search", u"comment"), 'comment__iexact' ), - 'additional_information': ( + 'additional_information': SearchAltName( pgettext_lazy("key for text search", u"additional-information"), 'additional_information__iexact' ), - 'duplicate': ( + 'duplicate': SearchAltName( pgettext_lazy("key for text search", u"has-duplicate"), 'duplicate' ), - 'operation': ( + 'operation': SearchAltName( pgettext_lazy("key for text search", u"operation"), 'operations__cached_label__iexact' ), - 'context_record': ( + 'context_record': SearchAltName( pgettext_lazy("key for text search", u"context-record"), 'context_records__cached_label__iexact' ), - 'find': ( + 'find': SearchAltName( pgettext_lazy("key for text search", u"find"), 'finds__cached_label__iexact' ), - 'find__denomination': ( + 'find__denomination': SearchAltName( pgettext_lazy("key for text search", u"find-denomination"), 'finds__denomination__iexact' ), - 'file': ( + 'file': SearchAltName( pgettext_lazy("key for text search", u"file"), 'files__cached_label__iexact' ), - 'site': ( + 'site': SearchAltName( pgettext_lazy("key for text search", u"site"), 'sites__cached_label__iexact' ), - 'warehouse': ( + 'warehouse': SearchAltName( pgettext_lazy("key for text search", u"warehouse"), 'warehouses__name__iexact' ), } - for v in ALT_NAMES.values(): - for language_code, language_lbl in settings.LANGUAGES: - activate(language_code) - EXTRA_REQUEST_KEYS[unicode(v[0])] = v[1] - deactivate() + objects = ExternalIdManager() RELATED_MODELS_ALT = [ diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 8af79c6fa..437bbd651 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -32,7 +32,7 @@ from weasyprint.fonts import FontConfiguration from ishtar_common.utils import check_model_access_control, CSV_OPTIONS, \ get_all_field_names from ishtar_common.models import HistoryError, get_current_profile, \ - PRIVATE_FIELDS, GeneralType + PRIVATE_FIELDS, GeneralType, SearchAltName from menus import Menu import models @@ -381,21 +381,23 @@ FORBIDDEN_CHAR = [u":"] RESERVED_CHAR = [u"|", u"&"] -def _parse_query_string(string, request_keys, current_dct, exc_dct): +def _parse_query_string(string, query_parameters, current_dct, exc_dct, + extra_distinct_q): string = string.strip().lower() if u"=" in string: splited = string.split(u"=") if len(splited) == 2: - term, query = splited - excluded = term.startswith(u"-") + base_term, query = splited + excluded = base_term.startswith(u"-") if excluded: - term = term[1:] - if term in request_keys: + base_term = base_term[1:] + if base_term in query_parameters: dct = current_dct - term = request_keys[term] + term = query_parameters[base_term].search_query # callable request key for complex queries if callable(term): + # !! distinct_queries not managed is_true = is_true_string(query) if excluded: is_true = not is_true @@ -411,12 +413,26 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct): if cextra: dct['extras'].append(cextra) else: - if excluded: + if query_parameters[base_term].distinct_query: + extra_distinct_q.append({}) + dct = extra_distinct_q[-1] + if not query_parameters[base_term].distinct_query and \ + excluded: dct = exc_dct + if query_parameters[base_term].extra_query: + dct.update(query_parameters[base_term].extra_query) if term in dct: dct[term] += u";" + query else: dct[term] = query + if query_parameters[base_term].distinct_query: + for k in dct: # clean " + dct[k] = dct[k].replace('"', '') + # distinct query wait for a query + if excluded: + extra_distinct_q[-1] = ~Q(**dct) + else: + extra_distinct_q[-1] = Q(**dct) return u"" for reserved_char in FORBIDDEN_CHAR: string = string.replace(reserved_char, u"") @@ -436,21 +452,24 @@ def _parse_query_string(string, request_keys, current_dct, exc_dct): return string -def _parse_parentheses_groups(groups, request_keys, current_dct=None, - exc_dct=None): +def _parse_parentheses_groups(groups, query_parameters, current_dct=None, + exc_dct=None, extra_distinct_q=None): """ Transform parentheses groups to query :param groups: groups to transform (list) - :param request_keys: request keys for facet search + :param query_parameters: query keys for facet search :param current_dct: query dict :param exc_dct: exclude query dict + :param exc_dct: exclude query dict :return: query string, query dict, excluded query dict """ if not current_dct: current_dct = {} if not exc_dct: exc_dct = {} + if not extra_distinct_q: + extra_distinct_q = [] if type(groups) is not list: string = groups.strip() if string.startswith(u'"') and string.endswith(u'"') and \ @@ -479,17 +498,19 @@ def _parse_parentheses_groups(groups, request_keys, current_dct=None, string_groups = [gp.replace(SEP, u" ") for gp in string.split(u" ")] if len(string_groups) == 1: return _parse_query_string( - string_groups[0], request_keys, current_dct, exc_dct), \ - current_dct, exc_dct - return _parse_parentheses_groups(string_groups, - request_keys, current_dct, exc_dct) + string_groups[0], query_parameters, current_dct, exc_dct, + extra_distinct_q + ), current_dct, exc_dct, extra_distinct_q + return _parse_parentheses_groups( + string_groups, query_parameters, current_dct, exc_dct, + extra_distinct_q) if not groups: # empty list - return "", current_dct, exc_dct + return "", current_dct, exc_dct, extra_distinct_q query = u"(" previous_sep, has_item = None, False for item in groups: - q, current_dct, exc_dct = _parse_parentheses_groups( - item, request_keys, current_dct, exc_dct) + q, current_dct, exc_dct, extra_distinct_q = _parse_parentheses_groups( + item, query_parameters, current_dct, exc_dct, extra_distinct_q) q = q.strip() if not q: continue @@ -509,18 +530,20 @@ def _parse_parentheses_groups(groups, request_keys, current_dct=None, query += u")" if query == u"()": query = u"" - return unidecode(query), current_dct, exc_dct + return unidecode(query), current_dct, exc_dct, extra_distinct_q -def _search_manage_search_vector(model, dct, exc_dct, request_keys): +def _search_manage_search_vector(model, dct, exc_dct, distinct_queries, + query_parameters): if 'search_vector' not in dct: - return dct, exc_dct + return dct, exc_dct, distinct_queries search_vector = dct['search_vector'] parentheses_groups = _parse_parentheses(search_vector) - search_query, extra_dct, extra_exc_dct = _parse_parentheses_groups( - parentheses_groups, request_keys) + search_query, extra_dct, extra_exc_dct, extra_distinct_q = \ + _parse_parentheses_groups(parentheses_groups, query_parameters) dct.update(extra_dct) + distinct_queries += extra_distinct_q exc_dct.update(extra_exc_dct) if search_query: @@ -536,7 +559,7 @@ def _search_manage_search_vector(model, dct, exc_dct, request_keys): 'params': [settings.ISHTAR_SEARCH_LANGUAGE, search_query]} ) - return dct, exc_dct + return dct, exc_dct, distinct_queries def _manage_bool_fields(model, bool_fields, reversed_bool_fields, dct, or_reqs): @@ -1033,11 +1056,18 @@ def get_item(model, func_name, default_name, extra_request_keys=None, else: query_own = model.get_query_owns(q.all()[0]) + query_parameters = {} + + if hasattr(model, 'get_query_parameters'): + query_parameters = model.get_query_parameters() + # get defaults from model - if not extra_request_keys and hasattr(model, 'EXTRA_REQUEST_KEYS'): + if not extra_request_keys and query_parameters: my_extra_request_keys = copy(model.EXTRA_REQUEST_KEYS) + for key in query_parameters: + my_extra_request_keys[key] = query_parameters[key].search_query else: - my_extra_request_keys = copy(extra_request_keys or []) + my_extra_request_keys = copy(extra_request_keys or {}) if base_request is None and hasattr(model, 'BASE_REQUEST'): if callable(model.BASE_REQUEST): my_base_request = model.BASE_REQUEST(request) @@ -1139,6 +1169,7 @@ def get_item(model, func_name, default_name, extra_request_keys=None, excluded_dct = {} and_reqs, or_reqs = [], [] exc_and_reqs, exc_or_reqs = [], [] + distinct_queries = [] dct['extras'], dct['and_reqs'], dct['exc_and_reqs'] = [], [], [] if full == 'shortcut': @@ -1158,11 +1189,19 @@ def get_item(model, func_name, default_name, extra_request_keys=None, if not val: continue req_keys = request_keys[k] + target = dct + if k in query_parameters: + if query_parameters[k].distinct_query: + distinct_queries.append({}) + target = distinct_queries[-1] + if query_parameters[k].extra_query: + target.update(query_parameters[k].extra_query) + if callable(req_keys): # callable request key for complex queries not managed on GET continue elif type(req_keys) not in (list, tuple): - dct[req_keys] = val + target[req_keys] = val continue # multiple choice target reqs = Q(**{req_keys[0]: val}) @@ -1184,8 +1223,14 @@ def get_item(model, func_name, default_name, extra_request_keys=None, else: request.session[func_name] = dct - dct, excluded_dct = _search_manage_search_vector( - model, dct, excluded_dct, request_keys) + for k in request_keys: + if k not in query_parameters: + query_parameters[k] = SearchAltName(k, request_keys[k]) + + dct, excluded_dct, distinct_queries = _search_manage_search_vector( + model, dct, excluded_dct, distinct_queries, query_parameters, + ) + search_vector = "" if 'search_vector' in dct: search_vector = dct.pop('search_vector') @@ -1254,9 +1299,12 @@ def get_item(model, func_name, default_name, extra_request_keys=None, if current: dct = {upper_key: current} query &= Q(**dct) - # print(query) items = model.objects.filter(query) + for d_q in distinct_queries: + print(d_q) + items = items.filter(d_q) + if base_query: items = items.filter(base_query) if exc_query: @@ -1422,9 +1470,8 @@ def get_item(model, func_name, default_name, extra_request_keys=None, keys = [keys] my_vals = [] for k in keys: - if hasattr(model, 'EXTRA_REQUEST_KEYS') \ - and k in model.EXTRA_REQUEST_KEYS: - k = model.EXTRA_REQUEST_KEYS[k] + if k in my_extra_request_keys: + k = my_extra_request_keys[k] if type(k) in (list, tuple): k = k[0] for filtr in ('__icontains', '__contains', '__iexact', |