diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-08-18 13:44:22 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-08-18 13:44:22 +0200 |
commit | a6d2faa3ffaa9f468ab17e121be02ce0d7495b99 (patch) | |
tree | 838b2a369a6b10261bb8269366ae5666cb62ecaf | |
parent | 8bbc6ecf7389357455739154ff1101dc2c1c42d5 (diff) | |
download | Ishtar-a6d2faa3ffaa9f468ab17e121be02ce0d7495b99.tar.bz2 Ishtar-a6d2faa3ffaa9f468ab17e121be02ce0d7495b99.zip |
Manage operation relation types in context record and find searches (refs #2799)
-rw-r--r-- | archaeological_context_records/forms.py | 10 | ||||
-rw-r--r-- | archaeological_context_records/tests.py | 39 | ||||
-rw-r--r-- | archaeological_context_records/views.py | 1 | ||||
-rw-r--r-- | archaeological_finds/forms.py | 15 | ||||
-rw-r--r-- | archaeological_finds/views.py | 3 | ||||
-rw-r--r-- | archaeological_operations/tests.py | 7 | ||||
-rw-r--r-- | ishtar_common/views.py | 47 |
7 files changed, 101 insertions, 21 deletions
diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py index 7572b0bcb..512d2069b 100644 --- a/archaeological_context_records/forms.py +++ b/archaeological_context_records/forms.py @@ -30,7 +30,7 @@ from django.utils.translation import ugettext_lazy as _ from ishtar_common.models import valid_id from archaeological_operations.models import Period, Parcel, Operation, \ - ArchaeologicalSite + ArchaeologicalSite, RelationType as OpeRelationType import models from ishtar_common import widgets @@ -56,6 +56,9 @@ class RecordSelect(TableSelect): reverse_lazy('autocomplete-archaeologicalsite'), associated_model=ArchaeologicalSite), validators=[valid_id(ArchaeologicalSite)]) + ope_relation_types = forms.MultipleChoiceField( + label=_(u"Search within operation relations"), choices=[], + widget=forms.CheckboxSelectMultiple) datings__period = forms.ChoiceField(label=_(u"Period"), choices=[]) unit = forms.ChoiceField(label=_(u"Unit type"), choices=[]) parcel = ParcelField(label=_(u"Parcel (section/number/public domain)")) @@ -71,6 +74,8 @@ class RecordSelect(TableSelect): self.fields['unit'].help_text = models.Unit.get_help() self.fields['relation_types'].choices = models.RelationType.get_types( empty_first=False) + self.fields['ope_relation_types'].choices = OpeRelationType.get_types( + empty_first=False) def get_input_ids(self): ids = super(RecordSelect, self).get_input_ids() @@ -81,6 +86,9 @@ class RecordSelect(TableSelect): ids.pop(ids.index('relation_types')) for idx, c in enumerate(self.fields['relation_types'].choices): ids.append('relation_types_{}'.format(idx)) + ids.pop(ids.index('ope_relation_types')) + for idx, c in enumerate(self.fields['ope_relation_types'].choices): + ids.append('ope_relation_types_{}'.format(idx)) return ids diff --git a/archaeological_context_records/tests.py b/archaeological_context_records/tests.py index 614156528..27ba0ab71 100644 --- a/archaeological_context_records/tests.py +++ b/archaeological_context_records/tests.py @@ -30,6 +30,7 @@ from ishtar_common.models import ImporterType, IshtarSiteProfile from ishtar_common.tests import create_superuser from archaeological_operations.tests import OperationInitTest, \ ImportOperationTest +from archaeological_operations import models as models_ope from archaeological_context_records import models from ishtar_common import forms_common @@ -126,18 +127,18 @@ class ContextRecordTest(ContextRecordInit, TestCase): def setUp(self): IshtarSiteProfile.objects.create() self.username, self.password, self.user = create_superuser() - self.create_context_record({"label": u"CR 1"}) - self.create_context_record({"label": u"CR 2"}) + self.create_context_record(data={"label": u"CR 1"}) + self.create_context_record(data={"label": u"CR 2"}) cr_1 = self.context_records[0] cr_2 = self.context_records[1] sym_rel_type = models.RelationType.objects.filter( symmetrical=True).all()[0] + self.cr_rel_type = sym_rel_type models.RecordRelations.objects.create( left_record=cr_1, right_record=cr_2, relation_type=sym_rel_type) def testSearchExport(self): - "url = reverse()get-contextrecord-full/csv?submited=1&" c = Client() response = c.get(reverse('get-contextrecord')) # no result when no authentification @@ -145,6 +146,38 @@ class ContextRecordTest(ContextRecordInit, TestCase): c.login(username=self.username, password=self.password) response = c.get(reverse('get-contextrecord')) self.assertTrue(json.loads(response.content)['total'] == 2) + # test search label + response = c.get(reverse('get-contextrecord'), + {'label': 'cr 1'}) + self.assertEqual(json.loads(response.content)['total'], 1) + # test search between relations + response = c.get(reverse('get-contextrecord'), + {'label': 'cr 1', + 'relation_types_0': self.cr_rel_type.pk}) + self.assertEqual(json.loads(response.content)['total'], 2) + # test search between operation relations + first_ope = self.operations[0] + first_ope.year = 2010 + first_ope.save() + cr_1 = self.context_records[0] + cr_1.operation = first_ope + cr_1.save() + other_ope = self.operations[1] + other_ope.year = 2016 + other_ope.save() + cr_2 = self.context_records[1] + cr_2.operation = other_ope + cr_2.save() + rel_ope = models_ope.RelationType.objects.create( + symmetrical=True, label='Linked', txt_idx='link') + models_ope.RecordRelations.objects.create( + left_record=other_ope, + right_record=first_ope, + relation_type=rel_ope) + response = c.get(reverse('get-contextrecord'), + {'operation__year': 2010, + 'ope_relation_types_0': rel_ope.pk}) + self.assertEqual(json.loads(response.content)['total'], 2) # export response = c.get(reverse('get-contextrecord-full', kwargs={'type': 'csv'}), {'submited': '1'}) diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py index 1b8585b82..4e3dcf7fe 100644 --- a/archaeological_context_records/views.py +++ b/archaeological_context_records/views.py @@ -80,6 +80,7 @@ def autocomplete_contextrecord(request): get_contextrecord = get_item( models.ContextRecord, 'get_contextrecord', 'contextrecord', + relation_types_prefix={'ope_relation_types': 'operation__'}, extra_request_keys=contextrecord_extra_keys,) get_contextrecord_for_ope = get_item( models.ContextRecord, diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py index 7b9c68d75..ba6426cae 100644 --- a/archaeological_finds/forms.py +++ b/archaeological_finds/forms.py @@ -30,7 +30,8 @@ from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ from ishtar_common.models import Person, valid_id, valid_ids -from archaeological_operations.models import Period, ArchaeologicalSite +from archaeological_operations.models import Period, ArchaeologicalSite, \ + RelationType as OpeRelationType from archaeological_context_records.models import DatingType, DatingQuality, \ ContextRecord from archaeological_warehouse.models import Warehouse @@ -210,6 +211,9 @@ class FindSelect(TableSelect): reverse_lazy('autocomplete-archaeologicalsite'), associated_model=ArchaeologicalSite), validators=[valid_id(ArchaeologicalSite)]) + ope_relation_types = forms.MultipleChoiceField( + label=_(u"Search within operation relations"), choices=[], + widget=forms.CheckboxSelectMultiple) datings__period = forms.ChoiceField(label=_(u"Period"), choices=[]) # TODO search by warehouse material_types = forms.ChoiceField(label=_(u"Material type"), choices=[]) @@ -256,6 +260,15 @@ class FindSelect(TableSelect): models.RemarkabilityType.get_types() self.fields['remarkabilities'].help_text = \ models.RemarkabilityType.get_help() + self.fields['ope_relation_types'].choices = OpeRelationType.get_types( + empty_first=False) + + def get_input_ids(self): + ids = super(FindSelect, self).get_input_ids() + ids.pop(ids.index('ope_relation_types')) + for idx, c in enumerate(self.fields['ope_relation_types'].choices): + ids.append('ope_relation_types_{}'.format(idx)) + return ids class FindFormSelection(forms.Form): diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py index dc8b191ad..20f73c321 100644 --- a/archaeological_finds/views.py +++ b/archaeological_finds/views.py @@ -69,6 +69,9 @@ find_extra_keys = { get_find = get_item( models.Find, 'get_find', 'find', reversed_bool_fields=['image__isnull'], + relation_types_prefix={ + 'ope_relation_types': + 'base_finds__context_record__operation__'}, base_request={'downstream_treatment__isnull': True}, extra_request_keys=find_extra_keys.copy()) diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index a7ca114f0..2bf3a6691 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -467,11 +467,10 @@ class OperationInitTest(object): return self.towns def get_default_town(self): - town = getattr(self, 'towns', None) - if not town: + towns = getattr(self, 'towns', None) + if not towns: self.create_towns() - town = self.towns[0] - return town + return self.towns[0] def create_parcel(self, data={}): default = {'town': self.get_default_town(), diff --git a/ishtar_common/views.py b/ishtar_common/views.py index d89e35bee..f5471583c 100644 --- a/ishtar_common/views.py +++ b/ishtar_common/views.py @@ -19,6 +19,7 @@ from tidylib import tidy_document as tidy +from copy import copy import csv import cStringIO as StringIO import datetime @@ -342,7 +343,7 @@ HIERARCHIC_FIELDS = ['periods', 'period', 'unit', 'material_types', def get_item(model, func_name, default_name, extra_request_keys=[], base_request={}, bool_fields=[], reversed_bool_fields=[], dated_fields=[], associated_models=[], relative_session_names={}, - specific_perms=[], own_table_cols=None): + specific_perms=[], own_table_cols=None, relation_types_prefix={}): """ Generic treatment of tables """ @@ -406,11 +407,19 @@ def get_item(model, func_name, default_name, extra_request_keys=[], except ValueError: return HttpResponse('[]', mimetype='text/plain') - relation_types = set() - for k in request_items: - if k.startswith('relation_types_'): - relation_types.add(request_items[k]) - continue + # manage relations types + my_rtypes_prefix = copy(relation_types_prefix) + if 'relation_types' not in my_rtypes_prefix: + my_rtypes_prefix['relation_types'] = '' + relation_types = {} + for rtype_key in my_rtypes_prefix: + relation_types[my_rtypes_prefix[rtype_key]] = set() + for k in request_items: + if k.startswith(rtype_key): + relation_types[my_rtypes_prefix[rtype_key]].add( + request_items[k]) + continue + for k in request_keys: val = request_items.get(k) if not val: @@ -509,14 +518,26 @@ def get_item(model, func_name, default_name, extra_request_keys=[], alt_dct.update(or_req) query = query | Q(**alt_dct) - if relation_types: + for rtype_prefix in relation_types: + vals = list(relation_types[rtype_prefix]) + if not vals: + continue alt_dct = { - 'right_relations__relation_type__pk__in': list(relation_types)} + rtype_prefix + 'right_relations__relation_type__pk__in': vals} for k in dct: val = dct[k] - if k == 'year': - k = 'year__exact' - alt_dct['right_relations__right_record__' + k] = val + if rtype_prefix: + # only get conditions related to the object + if rtype_prefix not in k: + continue + # tricky: reconstruct the key to make sense - remove the + # prefix from the key + k = k[0:k.index(rtype_prefix)] + k[ + k.index(rtype_prefix) + len(rtype_prefix):] + if k.endswith('year'): + k += '__exact' + alt_dct[rtype_prefix + 'right_relations__right_record__' + k] =\ + val if not dct: # fake condition to trick Django (1.4): without it only the # alt_dct is managed @@ -529,7 +550,9 @@ def get_item(model, func_name, default_name, extra_request_keys=[], val = or_req[j] if j == 'year': j = 'year__exact' - altor_dct['right_relations__right_record__' + j] = val + altor_dct[ + rtype_prefix + 'right_relations__right_record__' + j] =\ + val query = query | Q(**altor_dct) if own: |