summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2018-08-09 13:09:00 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2018-08-13 18:26:04 +0200
commita9597946a8c9a1a7de2c590ef0b87d2949994920 (patch)
tree65cfe7698eb328526dca64e7f36a66aa8b545f73
parentfccd2510276e510132d121cd88e76d62b1899122 (diff)
downloadIshtar-a9597946a8c9a1a7de2c590ef0b87d2949994920.tar.bz2
Ishtar-a9597946a8c9a1a7de2c590ef0b87d2949994920.zip
Record quality: migrate to a type
-rw-r--r--archaeological_operations/forms.py34
-rw-r--r--archaeological_operations/migrations/0034_archaeologicalsite_cached_label.py20
-rw-r--r--archaeological_operations/migrations/0035_auto_20180809_1152.py88
-rw-r--r--archaeological_operations/migrations/0036_auto_20180809_1242.py23
-rw-r--r--archaeological_operations/models.py121
-rw-r--r--ishtar_common/models.py1
-rw-r--r--ishtar_common/views_item.py18
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 = "&nbsp; "
PREFIX_MEDIUM = "&#x251C; "
PREFIX_LAST = "&#x2514; "
+ 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):