summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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
commita6d2faa3ffaa9f468ab17e121be02ce0d7495b99 (patch)
tree838b2a369a6b10261bb8269366ae5666cb62ecaf
parent8bbc6ecf7389357455739154ff1101dc2c1c42d5 (diff)
downloadIshtar-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.py10
-rw-r--r--archaeological_context_records/tests.py39
-rw-r--r--archaeological_context_records/views.py1
-rw-r--r--archaeological_finds/forms.py15
-rw-r--r--archaeological_finds/views.py3
-rw-r--r--archaeological_operations/tests.py7
-rw-r--r--ishtar_common/views.py47
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: