summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2016-01-27 19:24:00 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2016-01-27 19:24:00 +0100
commit29fe73d51ae8e50caffe5bb6e0cf2ba939d9a70d (patch)
tree8bf97c52e86a824093db25131ea12243e96ecd3b
parent995fa47d8cb0a9e2922cde89b7eaaf61968fe343 (diff)
downloadIshtar-29fe73d51ae8e50caffe5bb6e0cf2ba939d9a70d.tar.bz2
Ishtar-29fe73d51ae8e50caffe5bb6e0cf2ba939d9a70d.zip
Manage relation types in searches - relation type search for operations
-rw-r--r--archaeological_operations/forms.py10
-rw-r--r--archaeological_operations/models.py2
-rw-r--r--archaeological_operations/tests.py25
-rw-r--r--ishtar_common/templates/blocks/JQueryJqGrid.html10
-rw-r--r--ishtar_common/views.py37
5 files changed, 77 insertions, 7 deletions
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py
index ec66a2a7a..294e3163c 100644
--- a/archaeological_operations/forms.py
+++ b/archaeological_operations/forms.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -464,6 +464,9 @@ class OperationSelect(TableSelect):
report_processing = forms.ChoiceField(label=_(u"Report processing"),
choices=[])
virtual_operation = forms.NullBooleanField(label=_(u"Virtual operation"))
+ relation_types = forms.MultipleChoiceField(
+ label=_(u"Search within relations"), choices=[],
+ widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
super(OperationSelect, self).__init__(*args, **kwargs)
@@ -481,12 +484,17 @@ class OperationSelect(TableSelect):
self.fields['periods'].help_text = models.Period.get_help()
self.fields['record_quality'].choices = \
[('', '--')] + list(models.QUALITY)
+ self.fields['relation_types'].choices = models.RelationType.get_types(
+ empty_first=False)
def get_input_ids(self):
ids = super(OperationSelect, self).get_input_ids()
ids.pop(ids.index('parcel'))
ids.append('parcel_0')
ids.append('parcel_1')
+ ids.pop(ids.index('relation_types'))
+ for idx, c in enumerate(self.fields['relation_types'].choices):
+ ids.append('relation_types_{}'.format(idx))
return ids
diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py
index 795c1a805..2703db245 100644
--- a/archaeological_operations/models.py
+++ b/archaeological_operations/models.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2012-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2012-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py
index 91ec1deb0..578382ccd 100644
--- a/archaeological_operations/tests.py
+++ b/archaeological_operations/tests.py
@@ -514,9 +514,9 @@ class OperationInitTest(object):
class OperationTest(TestCase, OperationInitTest):
fixtures = [settings.ROOT_PATH +
- '../fixtures/initial_data.json',
+ '../fixtures/initial_data-auth-fr.json',
settings.ROOT_PATH +
- '../ishtar_common/fixtures/initial_data.json',
+ '../ishtar_common/fixtures/initial_data-fr.json',
settings.ROOT_PATH +
'../archaeological_files/fixtures/initial_data.json',
settings.ROOT_PATH +
@@ -544,6 +544,27 @@ class OperationTest(TestCase, OperationInitTest):
{'operator': self.orgas[0].pk})
self.assertTrue(json.loads(response.content)['total'] == 2)
+ def testRelatedSearch(self):
+ c = Client()
+ rel1 = models.RelationType.objects.create(
+ symmetrical=True, label='Include', txt_idx='include')
+ rel2 = models.RelationType.objects.create(
+ symmetrical=False, label='Included', txt_idx='included',
+ inverse_relation=rel1)
+ models.RecordRelations.objects.create(
+ left_record=self.operations[0],
+ right_record=self.operations[1],
+ relation_type=rel1)
+ self.operations[1].year = 2011
+ self.operations[1].save()
+ search = {'year': '2010', 'relation_types_0': rel2.pk}
+ response = c.get(reverse('get-operation'), search)
+ # no result when no authentification
+ self.assertTrue(not json.loads(response.content))
+ c.login(username=self.username, password=self.password)
+ response = c.get(reverse('get-operation'), search)
+ self.assertTrue(json.loads(response.content)['total'] == 2)
+
def testOwnSearch(self):
c = Client()
response = c.get(reverse('get-operation'), {'year': '2010'})
diff --git a/ishtar_common/templates/blocks/JQueryJqGrid.html b/ishtar_common/templates/blocks/JQueryJqGrid.html
index e8647dadf..bba1ef784 100644
--- a/ishtar_common/templates/blocks/JQueryJqGrid.html
+++ b/ishtar_common/templates/blocks/JQueryJqGrid.html
@@ -42,7 +42,15 @@ jQuery(document).ready(function(){
for (idx in query_vars)
{
var key = query_vars[idx];
- var val = jQuery("#id_"+key).val();
+ var item = jQuery("#id_"+key);
+ var val = null;
+ if (item.prop('type') == 'checkbox'){
+ if (item.prop('checked')){
+ var val = item.val();
+ }
+ } else {
+ var val = item.val();
+ }
if (val){
if (data) data += "&";
data += key + "=" + val;
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 1f2bc7f67..50acd5595 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -378,6 +378,13 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
old = 'old' in request_items and int(request_items['old'])
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
+
for k in request_keys:
val = request_items.get(k)
if not val:
@@ -460,15 +467,41 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
and_reqs.append(reqs)
break
query = Q(**dct)
- if own:
- query = query & model.get_query_owns(request.user)
for k, or_req in or_reqs:
alt_dct = dct.copy()
alt_dct.pop(k)
alt_dct.update(or_req)
query = query | Q(**alt_dct)
+
+ if relation_types:
+ alt_dct = {
+ 'right_relations__relation_type__pk__in': list(relation_types)}
+ for k in dct:
+ val = dct[k]
+ if k == 'year':
+ k = 'year__exact'
+ alt_dct['right_relations__right_record__' + k] = val
+ if not dct:
+ # fake condition to trick Django (1.4): without it only the
+ # alt_dct is managed
+ query = query & Q(pk__isnull=False)
+ query = query | Q(**alt_dct)
+ for k, or_req in or_reqs:
+ altor_dct = alt_dct.copy()
+ altor_dct.pop(k)
+ for j in or_req:
+ val = or_req[j]
+ if j == 'year':
+ j = 'year__exact'
+ altor_dct['right_relations__right_record__' + j] = val
+ query = query | Q(**altor_dct)
+
+ if own:
+ query = query & model.get_query_owns(request.user)
+
for and_req in and_reqs:
query = query & and_req
+
items = model.objects.filter(query).distinct()
q = request_items.get('sidx')