diff options
-rw-r--r-- | archaeological_operations/forms.py | 34 | ||||
-rw-r--r-- | archaeological_operations/migrations/0034_archaeologicalsite_cached_label.py | 20 | ||||
-rw-r--r-- | archaeological_operations/migrations/0035_auto_20180809_1152.py | 88 | ||||
-rw-r--r-- | archaeological_operations/migrations/0036_auto_20180809_1242.py | 23 | ||||
-rw-r--r-- | archaeological_operations/models.py | 121 | ||||
-rw-r--r-- | ishtar_common/models.py | 1 | ||||
-rw-r--r-- | ishtar_common/views_item.py | 18 |
7 files changed, 258 insertions, 47 deletions
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py index 63b350f28..20379e588 100644 --- a/archaeological_operations/forms.py +++ b/archaeological_operations/forms.py @@ -530,7 +530,7 @@ class OperationSelect(TableSelect): abstract = forms.CharField(label=_(u"Abstract (full text search)")) scientific_documentation_comment = forms.CharField( label=_(u"Comment about scientific documentation")) - record_quality = forms.ChoiceField(label=_(u"Record quality")) + record_quality_type = forms.ChoiceField(label=_(u"Record quality")) report_processing = forms.ChoiceField(label=_(u"Report processing"), choices=[]) virtual_operation = forms.NullBooleanField(label=_(u"Virtual operation")) @@ -553,18 +553,27 @@ class OperationSelect(TableSelect): args=['0', 'user']), associated_model=Person), validators=[valid_id(Person)]) + documentation_received = forms.NullBooleanField( + label=_(u"Documentation received")) documentation_deadline_before = DateField( label=_(u"Documentation deadline before")) documentation_deadline_after = DateField( label=_(u"Documentation deadline after")) - documentation_received = forms.NullBooleanField( - label=_(u"Documentation received")) + finds_received = forms.NullBooleanField( + label=_(u"Finds received")) finds_deadline_before = DateField( label=_(u"Finds deadline before")) finds_deadline_after = DateField( label=_(u"Finds deadline after")) - finds_received = forms.NullBooleanField( - label=_(u"Finds received")) + + TYPES = [ + FieldType('operation_type', models.OperationType), + FieldType('report_processing', models.ReportState), + FieldType('remains', models.RemainType), + FieldType('periods', models.Period), + FieldType('record_quality_type', models.RecordQualityType), + FieldType('relation_types', models.RelationType), + ] def __init__(self, *args, **kwargs): super(OperationSelect, self).__init__(*args, **kwargs) @@ -575,25 +584,10 @@ class OperationSelect(TableSelect): self.fields.pop('finds_deadline_before') self.fields.pop('finds_deadline_after') self.fields.pop('finds_received') - self.fields['operation_type'].choices = \ - models.OperationType.get_types() - self.fields['operation_type'].help_text = \ - models.OperationType.get_help() - self.fields['report_processing'].choices = \ - models.ReportState.get_types() - self.fields['report_processing'].help_text = \ - models.ReportState.get_help() - self.fields['remains'].choices = models.RemainType.get_types() - self.fields['remains'].help_text = models.RemainType.get_help() - self.fields['periods'].choices = models.Period.get_types() - self.fields['periods'].help_text = models.Period.get_help() - self.fields['record_quality'].choices = \ - [('', '--')] + list(models.QUALITY) if settings.ISHTAR_DPTS: k = 'towns__numero_insee__startswith' self.fields[k].choices = [ ('', '--')] + list(settings.ISHTAR_DPTS) - self.fields['relation_types'].choices = models.RelationType.get_types() class OperationFormSelection(IshtarForm): diff --git a/archaeological_operations/migrations/0034_archaeologicalsite_cached_label.py b/archaeological_operations/migrations/0034_archaeologicalsite_cached_label.py new file mode 100644 index 000000000..c4bd2e765 --- /dev/null +++ b/archaeological_operations/migrations/0034_archaeologicalsite_cached_label.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-08-08 18:58 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('archaeological_operations', '0033_parcel_cached_label'), + ] + + operations = [ + migrations.AddField( + model_name='archaeologicalsite', + name='cached_label', + field=models.TextField(blank=True, db_index=True, null=True, verbose_name='Cached name'), + ), + ] diff --git a/archaeological_operations/migrations/0035_auto_20180809_1152.py b/archaeological_operations/migrations/0035_auto_20180809_1152.py new file mode 100644 index 000000000..cb88d6119 --- /dev/null +++ b/archaeological_operations/migrations/0035_auto_20180809_1152.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-08-09 11:52 +from __future__ import unicode_literals + +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion +import ishtar_common.models +import re + + +def migrate_operation(apps, schema_editor): + Operation = apps.get_model('archaeological_operations', 'Operation') + RecordQualityType = apps.get_model('archaeological_operations', + 'RecordQualityType') + + not_documented, c = RecordQualityType.objects.get_or_create( + txt_idx=u"not-documented", + defaults={ + "label": u"Non documenté", + "order": 10 + } + ) + arbitrary, c = RecordQualityType.objects.get_or_create( + txt_idx=u"arbitrary", + defaults={ + "label": u"Arbitraire", + "order": 20 + } + ) + reliable, c = RecordQualityType.objects.get_or_create( + txt_idx=u"reliable", + defaults={ + "label": u"Fiable", + "order": 30 + } + ) + QUALITY = { + 'ND': not_documented, + 'A': arbitrary, + 'R': reliable + } + for operation in Operation.objects.all(): + if not operation.record_quality: + continue + if operation.record_quality not in QUALITY: + continue + operation.record_quality_type = QUALITY[operation.record_quality] + operation.skip_history_when_saving = True + operation.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('archaeological_operations', '0034_archaeologicalsite_cached_label'), + ] + + operations = [ + migrations.CreateModel( + name='RecordQualityType', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('label', models.TextField(verbose_name='Label')), + ('txt_idx', models.TextField(help_text='The slug is the standardized version of the name. It contains only lowercase letters, numbers and hyphens. Each slug must be unique.', unique=True, validators=[django.core.validators.RegexValidator(re.compile('^[-a-zA-Z0-9_]+\\Z'), "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens.", 'invalid')], verbose_name='Textual ID')), + ('comment', models.TextField(blank=True, null=True, verbose_name='Comment')), + ('available', models.BooleanField(default=True, verbose_name='Available')), + ('order', models.IntegerField(verbose_name='Order')), + ], + options={ + 'ordering': ('order',), + 'verbose_name': 'Type of record quality', + 'verbose_name_plural': 'Types of record quality', + }, + bases=(ishtar_common.models.Cached, models.Model), + ), + migrations.AddField( + model_name='historicaloperation', + name='record_quality_type', + field=models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to='archaeological_operations.RecordQualityType'), + ), + migrations.AddField( + model_name='operation', + name='record_quality_type', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='archaeological_operations.RecordQualityType', verbose_name='Record quality'), + ), + migrations.RunPython(migrate_operation), + ] diff --git a/archaeological_operations/migrations/0036_auto_20180809_1242.py b/archaeological_operations/migrations/0036_auto_20180809_1242.py new file mode 100644 index 000000000..9e8d89fa2 --- /dev/null +++ b/archaeological_operations/migrations/0036_auto_20180809_1242.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.10 on 2018-08-09 12:42 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('archaeological_operations', '0035_auto_20180809_1152'), + ] + + operations = [ + migrations.RemoveField( + model_name='historicaloperation', + name='record_quality', + ), + migrations.RemoveField( + model_name='operation', + name='record_quality', + ), + ] diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 6f083fe7f..035235b51 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -79,14 +79,24 @@ class ReportState(GeneralType): verbose_name_plural = _(u"Types of report state") ordering = ('order',) - def __unicode__(self): - return self.label - post_save.connect(post_save_cache, sender=ReportState) post_delete.connect(post_save_cache, sender=ReportState) +class RecordQualityType(GeneralType): + order = models.IntegerField(_(u"Order")) + + class Meta: + verbose_name = _(u"Type of record quality") + verbose_name_plural = _(u"Types of record quality") + ordering = ('order',) + + +post_save.connect(post_save_cache, sender=RecordQualityType) +post_delete.connect(post_save_cache, sender=RecordQualityType) + + class ArchaeologicalSite(BaseHistorizedItem): SHOW_URL = 'show-site' TABLE_COLS = ['reference', 'name', 'towns', 'periods', 'remains'] @@ -95,7 +105,7 @@ class ArchaeologicalSite(BaseHistorizedItem): "reference", "name", "oceanographic_service_localisation", "shipwreck_code", "comment", "shipwreck_name", "discovery_area", ] - M2M_SEARCH_VECTORS = ["periods__name", "remains__name", "towns__name"] + M2M_SEARCH_VECTORS = ["periods__label", "remains__label", "towns__name"] PARENT_SEARCH_VECTORS = ['operations'] reference = models.CharField(_(u"Reference"), max_length=200, unique=True) name = models.CharField(_(u"Name"), max_length=200, @@ -131,6 +141,8 @@ class ArchaeologicalSite(BaseHistorizedItem): documents = models.ManyToManyField( Document, related_name="sites", verbose_name=_(u"Documents"), blank=True) + cached_label = models.TextField(_(u"Cached name"), + null=True, blank=True, db_index=True) class Meta: verbose_name = _(u"Archaeological site") @@ -149,6 +161,12 @@ class ArchaeologicalSite(BaseHistorizedItem): ) def __unicode__(self): + if self.cached_label: + return self.cached_label + self.save() + return self.cached_label + + def _generate_cached_label(self): name = self.reference if self.name: name += u" %s %s" % (settings.JOINT, self.name) @@ -157,7 +175,7 @@ class ArchaeologicalSite(BaseHistorizedItem): for k, lbl in keys: if getattr(self, k).count(): name += lbl.format(u", ".join([ - v.name for v in getattr(self, k).all() + unicode(v) for v in getattr(self, k).all() ])) return name @@ -219,6 +237,9 @@ class ArchaeologicalSite(BaseHistorizedItem): ) +post_save.connect(cached_label_changed, sender=ArchaeologicalSite) + + def get_values_town_related(item, prefix, values): values[prefix + 'parcellist'] = item.render_parcels() values[prefix + 'towns'] = '' @@ -240,11 +261,6 @@ def get_values_town_related(item, prefix, values): return values -QUALITY = (('ND', _(u"Not documented")), - ('A', _(u"Arbitrary")), - ('R', _(u"Reliable")),) - - class ClosedItem(object): def closing(self): if self.is_active(): @@ -275,7 +291,6 @@ class ClosedItem(object): class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem, DashboardFormItem, RelationItem): - QUALITY_DICT = dict(QUALITY) SHOW_URL = 'show-operation' TABLE_COLS = ['year', 'towns', 'common_name', 'operation_type', 'start_date', 'excavation_end_date', 'remains'] @@ -309,8 +324,6 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, 'history_creator__ishtaruser__person__pk', 'history_modifier': 'history_modifier__ishtaruser__person__pk', - 'archaeological_sites': - 'archaeological_sites__pk', 'documentation_deadline_before': 'documentation_deadline__lte', 'documentation_deadline_after': 'documentation_deadline__gte', 'finds_deadline_before': 'finds_deadline__lte', @@ -384,15 +397,15 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, ), 'common_name': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"name"), - 'common_name' + 'common_name__icontains' ), 'address': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"address"), - 'address' + 'address__icontains' ), 'operation_type': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"type"), - 'operation_type__pk' + 'operation_type__label__iexact' ), 'end_date': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"is-open"), @@ -412,11 +425,11 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, ), 'remains': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"remain"), - 'remains__pk' + 'remains__label__iexact' ), 'periods': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"period"), - 'periods__pk' + 'periods__label__iexact' ), 'start_before': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"start-before"), @@ -437,7 +450,71 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, 'relation_types': ( pgettext_lazy(TXT_SEARCH_COMMENT, u"relation-types"), 'relation_types' - ) + ), + 'comment': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"comment"), + 'comment__icontains' + ), + 'abstract': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"abstract"), + 'abstract__icontains' + ), + 'scientific_documentation_comment': ( + pgettext_lazy(TXT_SEARCH_COMMENT, + u"scientific-documentation-comment"), + 'scientific_documentation_comment__icontains' + ), + 'record_quality_type': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"record-quality"), + 'record_quality_type__label__iexact' + ), + 'report_processing': ( + pgettext_lazy(TXT_SEARCH_COMMENT, + u"report-processing"), + 'report_processing__label__iexact' + ), + 'virtual_operation': ( + pgettext_lazy(TXT_SEARCH_COMMENT, + u"virtual_operation"), + 'virtual_operation' + ), + 'archaeological_sites': ( + pgettext_lazy(TXT_SEARCH_COMMENT, + u"site"), + 'archaeological_sites__cached_label__icontains' + ), + 'history_creator': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"created-by"), + 'history_creator__ishtaruser__person__cached_label__iexact' + ), + 'history_modifier': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"modified-by"), + 'history_modifier__ishtaruser__person__cached_label__iexact' + ), + 'documentation_received': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"documentation-received"), + 'documentation_received' + ), + 'documentation_deadline_before': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"documentation-deadline-before"), + 'documentation_deadline__lte' + ), + 'documentation_deadline_after': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"documentation-deadline-after"), + 'documentation_deadline__gte' + ), + 'finds_received': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"finds-received"), + 'finds_received' + ), + 'finds_deadline_before': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"finds-deadline-before"), + 'finds_deadline__lte' + ), + 'finds_deadline_after': ( + pgettext_lazy(TXT_SEARCH_COMMENT, u"finds-deadline-after"), + 'finds_deadline__gte' + ), } for v in ALT_NAMES.values(): EXTRA_REQUEST_KEYS[v[0]] = v[1] @@ -550,9 +627,9 @@ class Operation(ClosedItem, BaseHistorizedItem, OwnPerms, ValueGetter, default=False, help_text=_( u"If checked, it means that this operation have not been " u"officialy registered.")) - record_quality = models.CharField( - _(u"Record quality"), max_length=2, null=True, blank=True, - choices=QUALITY) + record_quality_type = models.ForeignKey( + RecordQualityType, verbose_name=_(u"Record quality"), + null=True, blank=True,) abstract = models.TextField(_(u"Abstract"), null=True, blank=True) documentation_deadline = models.DateField( _(u"Deadline for submission of the documentation"), blank=True, diff --git a/ishtar_common/models.py b/ishtar_common/models.py index e2b1d5b02..678e2ce41 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -652,6 +652,7 @@ class GeneralType(Cached, models.Model): PREFIX_EMPTY = " " PREFIX_MEDIUM = "├ " PREFIX_LAST = "└ " + PREFIX_CODES = [u"\u2502", u"\u251C", u"\u2514"] @classmethod def _get_childs(cls, item, dct, prefix=0, instances=False, exclude=[], diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py index 746d359c1..3b09bc7da 100644 --- a/ishtar_common/views_item.py +++ b/ishtar_common/views_item.py @@ -29,7 +29,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 + PRIVATE_FIELDS, GeneralType from menus import Menu import models @@ -492,6 +492,12 @@ def _manage_dated_fields(dated_fields, dct): dct.pop(k) +def _clean_type_val(val): + for prefix in GeneralType.PREFIX_CODES: + val = val.replace(prefix, u"") + return val.strip() + + def _manage_facet_search(model, dct, and_reqs): general_types = model.general_types() for base_k in general_types: @@ -501,7 +507,7 @@ def _manage_facet_search(model, dct, and_reqs): if k not in dct or not dct[k].startswith(u'"') \ or not dct[k].startswith(u'"'): continue - val = dct.pop(k) + val = _clean_type_val(dct.pop(k)) if u";" in val: # OR request values = val.split(u";") @@ -533,7 +539,7 @@ def _manage_facet_search(model, dct, and_reqs): def _manage_hierarchic_fields(dct, and_reqs): for req in dct.copy(): if req.endswith('areas__pk'): - val = dct.pop(req) + val = _clean_type_val(dct.pop(req)) reqs = Q(**{req: val}) base_req = req[:-2] + '__' req = base_req[:] @@ -550,7 +556,7 @@ def _manage_hierarchic_fields(dct, and_reqs): continue if req.endswith('town__pk') or req.endswith('towns__pk'): - val = dct.pop(req) + val = _clean_type_val(dct.pop(req)) reqs = Q(**{req: val}) base_req = req[:-2] + '__' req = base_req[:] @@ -571,6 +577,7 @@ def _manage_hierarchic_fields(dct, and_reqs): val = dct.pop(req) q = None for idx, r in enumerate(req): + r = _clean_type_val(r) if not idx: q = Q(**{r: val}) else: @@ -578,7 +585,7 @@ def _manage_hierarchic_fields(dct, and_reqs): and_reqs.append(q) break elif req.endswith(k_hr + '__pk'): - val = dct.pop(req) + val = _clean_type_val(dct.pop(req)) if u";" in val: # OR request @@ -619,6 +626,7 @@ def _manage_clean_search_field(dct): # clean quoted search field if type(dct[k]) == unicode: dct[k] = dct[k].replace(u'"', '') + dct[k] = _clean_type_val(dct[k]) def _manage_relation_types(relation_types, dct, query, or_reqs): |