diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2020-03-11 13:27:04 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2020-03-11 13:27:04 +0100 |
commit | 3fd126b25be6a50c49b4525941d216fa92f727b0 (patch) | |
tree | c248b4e8b129d017373af2a07d399f5ca82717b1 | |
parent | 9429df335283ff6de8c0e21778bb0e7fbda6b149 (diff) | |
download | Ishtar-3fd126b25be6a50c49b4525941d216fa92f727b0.tar.bz2 Ishtar-3fd126b25be6a50c49b4525941d216fa92f727b0.zip |
Searc criteria: add has image/file/url criteria for all document items
-rw-r--r-- | CHANGES.md | 10 | ||||
-rw-r--r-- | archaeological_context_records/forms.py | 4 | ||||
-rw-r--r-- | archaeological_context_records/models.py | 6 | ||||
-rw-r--r-- | archaeological_files/forms.py | 6 | ||||
-rw-r--r-- | archaeological_files/models.py | 7 | ||||
-rw-r--r-- | archaeological_finds/forms.py | 15 | ||||
-rw-r--r-- | archaeological_finds/forms_treatments.py | 9 | ||||
-rw-r--r-- | archaeological_finds/models_finds.py | 9 | ||||
-rw-r--r-- | archaeological_finds/models_treatments.py | 17 | ||||
-rw-r--r-- | archaeological_operations/forms.py | 6 | ||||
-rw-r--r-- | archaeological_operations/models.py | 13 | ||||
-rw-r--r-- | archaeological_warehouse/forms.py | 4 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 6 | ||||
-rw-r--r-- | ishtar_common/forms.py | 24 | ||||
-rw-r--r-- | ishtar_common/models.py | 17 |
15 files changed, 115 insertions, 38 deletions
diff --git a/CHANGES.md b/CHANGES.md index b3907be7f..821d79c04 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,7 +1,7 @@ Ishtar changelog ================ -v3.0.4 - 2020-XX-XX +v3.0.4 - 2020-03-11 ------------------- ### Features ### - Quick actions - sheets: add duplicate for site, operation, document and context record @@ -17,6 +17,14 @@ v3.0.4 - 2020-XX-XX - operation: town, scientist - Warehouse: - town + - All document items: + - has associated file + - has associated image + - has associated url + +### Bug fixes ### +- Tables: fix display of links in columns +- Criteria search: manage empty field (but not NULL) multiple level search for file (including images) fields v3.0.3 - 2020-02-24 diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py index 87cad2c66..5ed9935e9 100644 --- a/archaeological_context_records/forms.py +++ b/archaeological_context_records/forms.py @@ -35,7 +35,7 @@ from archaeological_context_records import models from ishtar_common.forms import FinalForm, FormSet, \ reverse_lazy, get_form_selection, ManageOldType, CustomForm, \ FieldType, CustomFormSearch, IshtarForm, FormHeader, HistorySelect, \ - MultiSearchForm, LockForm + MultiSearchForm, LockForm, DocumentItemSelect from ishtar_common.forms_common import get_town_field from archaeological_operations.forms import OperationSelect, ParcelField, \ RecordRelationsForm as OpeRecordRelationsForm, RecordRelationsFormSetBase @@ -60,7 +60,7 @@ class OperationFormSelection(CustomForm, forms.Form): validators=[valid_id(Operation)]) -class RecordSelect(HistorySelect): +class RecordSelect(DocumentItemSelect): _model = models.ContextRecord form_admin_name = _(u"Context record - 001 - Search") form_slug = "contextrecord-001-search" diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index 9b1483e0d..02b074706 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -362,6 +362,11 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem, 'operation_id': 'operation_id', 'unit__label': "unit__label" } + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] RELATION_TYPES_PREFIX = {'ope_relation_types': 'operation__', 'cr_relation_types': ''} # alternative names of fields for searches @@ -416,6 +421,7 @@ class ContextRecord(BulkUpdatedItem, DocumentItem, BaseHistorizedItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) PARENT_ONLY_SEARCH_VECTORS = ["operation", "archaeological_site", "parcel"] BASE_SEARCH_VECTORS = [ diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py index 9a2f63a1d..a9936c47a 100644 --- a/archaeological_files/forms.py +++ b/archaeological_files/forms.py @@ -37,8 +37,8 @@ from archaeological_operations.models import ActType, AdministrativeAct, \ from . import models from ishtar_common.forms import FinalForm, get_now, reverse_lazy, TableSelect, \ - ManageOldType, CustomForm, FieldType, IshtarForm, HistorySelect, \ - MultiSearchForm, LockForm, CustomFormSearch + ManageOldType, CustomForm, FieldType, IshtarForm, \ + MultiSearchForm, LockForm, CustomFormSearch, DocumentItemSelect from ishtar_common.forms_common import get_town_field from archaeological_operations.forms import AdministrativeActForm, \ AdministrativeActOpeFormSelection, SLICING, AdministrativeActModifForm, \ @@ -47,7 +47,7 @@ from ishtar_common import widgets from bootstrap_datepicker.widgets import DatePicker -class FileSelect(HistorySelect): +class FileSelect(DocumentItemSelect): _model = models.File form_admin_name = _(u"File - 001 - Search") form_slug = "file-001-search" diff --git a/archaeological_files/models.py b/archaeological_files/models.py index 018b5d429..310301c59 100644 --- a/archaeological_files/models.py +++ b/archaeological_files/models.py @@ -161,6 +161,12 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, OwnPerms, ValueGetter, 'towns_label': _(u"Towns"), } + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] + # alternative names of fields for searches ALT_NAMES = { 'year': SearchAltName( @@ -230,6 +236,7 @@ class File(ClosedItem, DocumentItem, BaseHistorizedItem, OwnPerms, ValueGetter, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) POST_PROCESS_REQUEST = { 'towns__numero_insee__startswith': '_get_department_code', diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 316253a7a..90805e656 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -56,7 +56,7 @@ from ishtar_common import widgets from ishtar_common.forms import CustomForm, CustomFormSearch, FormSet, \ FloatField, reverse_lazy, TableSelect, get_now, FinalForm, \ ManageOldType, FieldType, IshtarForm, FormHeader, QAForm, HistorySelect, \ - MultiSearchForm, LockForm + MultiSearchForm, LockForm, DocumentItemSelect from ishtar_common.forms_common import get_town_field from ishtar_common.models import valid_id, valid_ids, get_current_profile, \ SpatialReferenceSystem, Area, OperationType, IshtarUser @@ -524,8 +524,8 @@ class ResultingFindsForm(CustomForm, ManageOldType): label=_(u"Prefix label for resulting finds"), validators=[validators.MaxLengthValidator(200)], help_text=_( - u'E.g.: with a prefix "item-", each resulting item will be named ' - u'"item-1", "item-2", "item-3"') + 'E.g.: with a prefix "item-", each resulting item will be named ' + '"item-1", "item-2", "item-3"') ) resultings_start_number = forms.IntegerField( label=_(u"Numbering starting from"), initial=1, min_value=0 @@ -908,9 +908,9 @@ DatingFormSet.form_admin_name = _(u"Find - 040 - Dating") DatingFormSet.form_slug = "find-040-dating" -class FindSelect(HistorySelect): +class FindSelect(DocumentItemSelect): _model = models.Find - form_admin_name = _(u"Find - 001 - Search") + form_admin_name = _("Find - 001 - Search") form_slug = "find-001-search" FORM_FILTERS = [ (_(u"Find origin"), [ @@ -1051,9 +1051,9 @@ class FindSelect(HistorySelect): reverse_lazy('autocomplete-materialtype'), associated_model=models.MaterialType), ) - material_type_quality = forms.ChoiceField(label=_(u"Material type quality"), + material_type_quality = forms.ChoiceField(label=_("Material type quality"), choices=[]) - material_comment = forms.CharField(label=_(u"Comment on the material")) + material_comment = forms.CharField(label=_("Comment on the material")) object_types = forms.IntegerField( label=_(u"Object type"), widget=widgets.JQueryAutoComplete( @@ -1182,7 +1182,6 @@ class FindSelect(HistorySelect): appraisal_date__before = forms.DateField( label=_(u"Appraisal date before"), widget=DatePicker) - documents__image__isnull = forms.NullBooleanField(label=_(u"Has an image?")) loan = forms.NullBooleanField(label=_(u"Loan?")) treatments_file_end_date = forms.DateField( label=_(u"Treatment file end date before"), widget=DatePicker diff --git a/archaeological_finds/forms_treatments.py b/archaeological_finds/forms_treatments.py index f03dec18a..b80b6c0fe 100644 --- a/archaeological_finds/forms_treatments.py +++ b/archaeological_finds/forms_treatments.py @@ -33,8 +33,8 @@ from archaeological_warehouse.models import Warehouse, Container from bootstrap_datepicker.widgets import DatePicker from ishtar_common import widgets from ishtar_common.forms import reverse_lazy, TableSelect, FinalForm, \ - ManageOldType, CustomForm, FieldType, IshtarForm, HistorySelect, \ - MultiSearchForm + ManageOldType, CustomForm, FieldType, IshtarForm, \ + DocumentItemSelect, MultiSearchForm from ishtar_common.models import Person, valid_id, valid_ids, Organization, \ get_current_profile @@ -43,7 +43,7 @@ logger = logging.getLogger(__name__) # Treatment -class TreatmentSelect(HistorySelect): +class TreatmentSelect(DocumentItemSelect): _model = models.Treatment form_admin_name = _(u"Treatment - 001 - Search") form_slug = "treatment-001-search" @@ -63,7 +63,6 @@ class TreatmentSelect(HistorySelect): associated_model=Person), label=_(u"Scientific monitoring manager")) treatment_types = forms.ChoiceField(label=_(u"Treatment type"), choices=[]) - documents__image__isnull = forms.NullBooleanField(label=_(u"Has an image?")) def __init__(self, *args, **kwargs): super(TreatmentSelect, self).__init__(*args, **kwargs) @@ -662,7 +661,7 @@ class AdministrativeActTreatmentModifForm( # treatment requests -class TreatmentFileSelect(HistorySelect): +class TreatmentFileSelect(DocumentItemSelect): _model = models.TreatmentFile form_admin_name = _(u"Treatment file - 001 - Search") form_slug = "treatmentfile-001-search" diff --git a/archaeological_finds/models_finds.py b/archaeological_finds/models_finds.py index ad5c803fa..328821386 100644 --- a/archaeological_finds/models_finds.py +++ b/archaeological_finds/models_finds.py @@ -880,7 +880,9 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, ) # search parameters - REVERSED_BOOL_FIELDS = ['documents__image__isnull'] + REVERSED_BOOL_FIELDS = ['documents__image__isnull', + 'documents__associated_url__isnull', + 'documents__associated_file__isnull'] BOOL_FIELDS = ['is_complete'] RELATION_TYPES_PREFIX = { 'ope_relation_types': @@ -1042,10 +1044,6 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, SearchAltName( pgettext_lazy("key for text search", "checked"), 'checked_type__label__iexact'), - 'documents__image__isnull': - SearchAltName( - pgettext_lazy("key for text search", "has-image"), - 'documents__image__isnull'), 'container_ref__location': SearchAltName( pgettext_lazy("key for text search", "location"), @@ -1364,6 +1362,7 @@ class Find(BulkUpdatedItem, ValueGetter, DocumentItem, BaseHistorizedItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) DYNAMIC_REQUESTS = { 'current_division': DynamicRequest( diff --git a/archaeological_finds/models_treatments.py b/archaeological_finds/models_treatments.py index a8a06ae27..071d80af1 100644 --- a/archaeological_finds/models_treatments.py +++ b/archaeological_finds/models_treatments.py @@ -74,7 +74,11 @@ class Treatment(DashboardFormItem, ValueGetter, DocumentItem, 'person__cached_label', 'start_date', 'downstream_cached_label', 'upstream_cached_label') - REVERSED_BOOL_FIELDS = ['documents__image__isnull'] + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] EXTRA_REQUEST_KEYS = { "downstream_cached_label": "downstream__cached_label", "upstream_cached_label": "upstream__cached_label", @@ -115,10 +119,6 @@ class Treatment(DashboardFormItem, ValueGetter, DocumentItem, pgettext_lazy("key for text search", "index"), 'index' ), - 'documents__image__isnull': SearchAltName( - pgettext_lazy("key for text search", "has-image"), - 'documents__image__isnull' - ), 'treatment_types': SearchAltName( pgettext_lazy("key for text search", "type"), 'treatment_types__label__iexact' @@ -129,6 +129,7 @@ class Treatment(DashboardFormItem, ValueGetter, DocumentItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) HISTORICAL_M2M = [ 'treatment_types', ] @@ -914,6 +915,11 @@ class TreatmentFile(DashboardFormItem, ClosedItem, DocumentItem, "in_charge__pk": "in_charge__pk", # used by dynamic_table_documents "applicant__pk": "applicant__pk", # used by dynamic_table_documents } + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] # alternative names of fields for searches ALT_NAMES = { 'name': SearchAltName( @@ -966,6 +972,7 @@ class TreatmentFile(DashboardFormItem, ClosedItem, DocumentItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) DATED_FIELDS = ['exhibition_start_date__lte', 'exhibition_start_date__gte', diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 9a3335df5..d665fc779 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -41,7 +41,7 @@ from ishtar_common import widgets from ishtar_common.forms import FinalForm, FormSet, get_now, \ reverse_lazy, TableSelect, get_data_from_formset, QAForm, CustomFormSearch,\ ManageOldType, IshtarForm, CustomForm, FieldType, FormHeader, \ - HistorySelect, LockForm, MultiSearchForm + DocumentItemSelect, LockForm, MultiSearchForm from ishtar_common.forms_common import TownFormSet, get_town_field, TownForm from ishtar_common.models import valid_id, valid_ids, Person, Town, \ DocumentTemplate, Organization, get_current_profile, \ @@ -472,7 +472,7 @@ RecordRelationsFormSet.form_admin_name = _(u"Operation - 080 - Relations") RecordRelationsFormSet.form_slug = "operation-080-relations" -class OperationSelect(HistorySelect): +class OperationSelect(DocumentItemSelect): _model = models.Operation form_admin_name = _(u"Operation - 001 - Search") form_slug = "operation-001-search" @@ -1367,7 +1367,7 @@ class OperationDeletionForm(FinalForm): ######### -class SiteSelect(HistorySelect): +class SiteSelect(DocumentItemSelect): _model = models.ArchaeologicalSite form_admin_name = _(u"Archaeological site - 001 - Search") form_slug = "archaeological_site-001-search" diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 8dd6568b8..8a415c0c5 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -180,6 +180,11 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, QRCodeItem, } # alternative names of fields for searches + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] ALT_NAMES = { 'reference': SearchAltName( pgettext_lazy("key for text search", "reference"), @@ -264,6 +269,7 @@ class ArchaeologicalSite(DocumentItem, BaseHistorizedItem, QRCodeItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) UP_MODEL_QUERY = { "operation": (pgettext_lazy("key for text search", "operation"), @@ -694,6 +700,11 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, QRCodeItem, # search parameters BOOL_FIELDS = ['end_date__isnull', 'virtual_operation', 'documentation_received', 'finds_received'] + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] DATED_FIELDS = [ 'start_date__lte', 'start_date__gte', 'excavation_end_date__lte', 'excavation_end_date__gte', 'documentation_deadline__lte', @@ -951,6 +962,8 @@ class Operation(ClosedItem, DocumentItem, BaseHistorizedItem, QRCodeItem, ), } ALT_NAMES.update(BaseHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) + QA_EDIT = QuickAction( url="operation-qa-bulk-update", icon_class="fa fa-pencil", text=_(u"Bulk update"), target="many", diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py index 867761047..a7b6c575e 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -42,7 +42,7 @@ from bootstrap_datepicker.widgets import DatePicker from ishtar_common.forms import name_validator, reverse_lazy, \ get_form_selection, ManageOldType, FinalForm, FormSet, \ - CustomForm, FieldType, HistorySelect, FormHeader, TableSelect, \ + CustomForm, FieldType, DocumentItemSelect, FormHeader, TableSelect, \ CustomFormSearch, MultiSearchForm, LockForm from ishtar_common.forms_common import get_town_field from archaeological_finds.forms import FindMultipleFormSelection, \ @@ -354,7 +354,7 @@ class ContainerModifyForm(ContainerForm): return cleaned_data -class ContainerSelect(HistorySelect): +class ContainerSelect(DocumentItemSelect): _model = models.Container form_admin_name = _(u"Container - 001 - Search") form_slug = "container-001-search" diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 325adce9e..63d4497ac 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -603,9 +603,15 @@ class Container(DocumentItem, LightHistorizedItem, QRCodeItem, GeoItem, ), } + REVERSED_BOOL_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + ] REVERSED_MANY_COUNTED_FIELDS = ['finds', 'finds_ref'] ALT_NAMES.update(LightHistorizedItem.ALT_NAMES) + ALT_NAMES.update(DocumentItem.ALT_NAMES) DYNAMIC_REQUESTS = { 'division': DynamicRequest( diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 17ada982f..939563334 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -782,23 +782,39 @@ class HistorySelect(CustomForm, TableSelect): label=_("Modified after"), widget=DatePicker, required=False) _explicit_ordering = True + CURRENT_FIELDS = ["history_creator", "history_modifier", + "modified_before", "modified_after"] def __init__(self, *args, **kwargs): super(HistorySelect, self).__init__(*args, **kwargs) field_order = self.fields.keys() - current_fields = ["history_creator", "history_modifier", - "modified_before", "modified_after"] fields = OrderedDict() for k in field_order: - if k in current_fields: + if k in self.CURRENT_FIELDS: continue fields[k] = self.fields[k] - for k in current_fields: + for k in self.CURRENT_FIELDS: fields[k] = self.fields[k] self.fields = fields self.custom_form_ordering() +class DocumentItemSelect(HistorySelect): + documents__image__isnull = forms.NullBooleanField(label=_("Has an image?")) + documents__associated_file__isnull = forms.NullBooleanField( + label=_("Has an attached file?")) + documents__associated_url__isnull = forms.NullBooleanField( + label=_("Has a web address?")) + CURRENT_FIELDS = [ + 'documents__image__isnull', + 'documents__associated_file__isnull', + 'documents__associated_url__isnull', + "history_creator", "history_modifier", + "modified_before", "modified_after" + ] + _explicit_ordering = True + + def get_now(): format = formats.get_format('DATE_INPUT_FORMATS')[0] value = datetime.datetime.now().strftime(format) diff --git a/ishtar_common/models.py b/ishtar_common/models.py index dc2fef815..5fa668faf 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1818,6 +1818,21 @@ class QRCodeItem(models.Model, ImageContainerModel): class DocumentItem(object): + ALT_NAMES = { + 'documents__image__isnull': + SearchAltName( + pgettext_lazy("key for text search", "has-image"), + 'documents__image__isnull'), + 'documents__associated_url__isnull': + SearchAltName( + pgettext_lazy("key for text search", "has-url"), + 'documents__associated_url__isnull'), + 'documents__associated_file__isnull': + SearchAltName( + pgettext_lazy("key for text search", "has-attached-file"), + 'documents__associated_file__isnull'), + } + def public_representation(self): images = [] if getattr(self, "main_image", None): @@ -5600,6 +5615,8 @@ class Document(BaseHistorizedItem, QRCodeItem, OwnPerms, ImageModel, no_path_change = 'no_path_change' in kwargs \ and kwargs.pop('no_path_change') self.set_index() + if not self.associated_url: + self.associated_url = None super(Document, self).save(*args, **kwargs) if self.image and not no_path_change and \ |