Skip to content

Commit

Permalink
Merge pull request #1218 from Signbank/lemma_search
Browse files Browse the repository at this point in the history
#1198: Rewrote queryset code of LemmaListView
  • Loading branch information
susanodd authored Apr 15, 2024
2 parents d5556a7 + f768af7 commit 879e5d6
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 56 deletions.
53 changes: 21 additions & 32 deletions signbank/dictionary/adminviews.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from django.core.paginator import Paginator
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.db.models import F, ExpressionWrapper, IntegerField, Count
from django.db.models import OuterRef, Subquery
Expand Down Expand Up @@ -5753,7 +5754,7 @@ def lemmaglosslist_ajax_complete(request, gloss_id):
class LemmaListView(ListView):
model = LemmaIdgloss
template_name = 'dictionary/admin_lemma_list.html'
paginate_by = 50
paginate_by = 100
show_all = False
search_type = 'lemma'
search_form = LemmaSearchForm()
Expand All @@ -5771,13 +5772,13 @@ def get_queryset(self, **kwargs):

get = self.request.GET

page_number = self.request.GET.get("page", 1)

# this view accommodates both Show All Lemmas and Lemma Search
# the show_all argument is True for Show All Lemmas
# if it is missing, a Lemma Search is being done and starts with no results
self.show_all = self.kwargs.get('show_all', False)

queryset = super(LemmaListView, self).get_queryset()

selected_datasets = get_selected_datasets_for_user(self.request.user)
dataset_languages = get_dataset_languages(selected_datasets)

Expand All @@ -5788,7 +5789,7 @@ def get_queryset(self, **kwargs):
qs = LemmaIdgloss.objects.none()
return qs

qs = queryset.filter(dataset__in=selected_datasets)
qs = LemmaIdgloss.objects.filter(dataset__in=selected_datasets).order_by('id')

if 'show_all_lemmas' in get and get['show_all_lemmas']:
self.show_all = True
Expand All @@ -5812,18 +5813,9 @@ def get_queryset(self, **kwargs):
language = Language.objects.get(language_code_2char=language_code_2char)
qs = qs.filter(lemmaidglosstranslation__text__icontains=get_value,
lemmaidglosstranslation__language=language)
return qs

def get_annotated_queryset(self, **kwargs):
# this method adds a gloss count column to the results for display
get = self.request.GET

qs = self.get_queryset()

if len(get) == 0:
results = qs.annotate(num_gloss=Count('gloss'))
num_gloss_zero_matches = results.filter(num_gloss=0).count()
return results, num_gloss_zero_matches
return qs

only_show_no_glosses = False
only_show_has_glosses = False
Expand All @@ -5837,14 +5829,10 @@ def get_annotated_queryset(self, **kwargs):
results = qs.annotate(num_gloss=Count('gloss'))
if only_show_no_glosses and not only_show_has_glosses:
results = results.filter(num_gloss=0)
num_gloss_zero_matches = results.count()
elif only_show_has_glosses and not only_show_no_glosses:
results = results.filter(num_gloss__gt=0)
num_gloss_zero_matches = 0
else:
num_gloss_zero_matches = results.filter(num_gloss=0).count()

return results, num_gloss_zero_matches
return results

def get_context_data(self, **kwargs):
context = super(LemmaListView, self).get_context_data(**kwargs)
Expand All @@ -5864,27 +5852,29 @@ def get_context_data(self, **kwargs):
context['populate_fields'] = json.dumps(populate_fields)
context['populate_fields_keys'] = json.dumps(populate_keys)

context['page_number'] = context['page_obj'].number
context['paginate_by'] = self.paginate_by

context['paginate_by'] = self.request.GET.get('paginate_by', self.paginate_by)
results = self.get_queryset()
context['is_paginated'] = results.count() > self.paginate_by

(results, num_gloss_zero_matches) = self.get_annotated_queryset()
page_number = self.request.GET.get("page", 1)

# this is set to avoid showing page numbers for non-existent pages after annotation filtering
context['is_paginated'] = results.count() > self.paginate_by
paginator = Paginator(results, self.paginate_by)
context['page_obj'] = paginator.get_page(page_number)

context['search_results'] = results
context['page_number'] = page_number

lemmas_zero_glosses = [lem for lem in results if lem.num_gloss == 0]
num_gloss_zero_matches = len(lemmas_zero_glosses)
context['num_gloss_zero_matches'] = num_gloss_zero_matches
context['lemma_count'] = LemmaIdgloss.objects.filter(dataset__in=selected_datasets).count()

context['search_matches'] = context['search_results'].count()
context['search_matches'] = results.count()

context['searchform'] = self.search_form
context['search_type'] = 'lemma'
context['show_all'] = self.show_all

list_of_objects = self.object_list

# to accommodate putting lemma's in the scroll bar in the LemmaUpdateView (aka LemmaDetailView),
# look at available translations, choose the Interface language if it is a Dataset language
# some legacy lemma's have missing translations,
Expand All @@ -5906,7 +5896,7 @@ def get_context_data(self, **kwargs):
# so the sorting of the scroll bar matches the default sorting of the results in Lemma List View
lang_attr_name = default_language_code

items = construct_scrollbar(list_of_objects, self.search_type, lang_attr_name)
items = construct_scrollbar(results, self.search_type, lang_attr_name)
self.request.session['search_results'] = items

return context
Expand All @@ -5928,7 +5918,7 @@ def render_to_csv_response(self):
header = csv_header_row_lemmalist(dataset_languages)
csv_rows = [header]

(queryset, num_gloss_zero_matches) = self.get_annotated_queryset()
queryset = self.get_queryset()
for lemma in queryset:
safe_row = csv_lemma_to_row(lemma, dataset_languages)
csv_rows.append(safe_row)
Expand Down Expand Up @@ -5962,12 +5952,11 @@ def post(self, request, *args, **kwargs):

selected_datasets = get_selected_datasets_for_user(self.request.user)

(queryset, num_gloss_zero_matches) = self.get_annotated_queryset()
queryset = self.get_queryset()

# check permissions, if fails, do nothing and show error message
for lemma in queryset:
if lemma.num_gloss == 0:
# the get_annotated_queryset which in turn calls get_queryset has already filtered on lemma's in the selected dataset
dataset_of_requested_lemma = lemma.dataset
if dataset_of_requested_lemma not in datasets_user_can_change:
messages.add_message(request, messages.WARNING,
Expand Down
4 changes: 4 additions & 0 deletions signbank/dictionary/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3259,6 +3259,10 @@ def __str__(self):
translations.append("{}".format(translation.text))
return ", ".join(translations)

def num_gloss(self):
glosses_with_this_lemma = Gloss.objects.filter(lemma__pk=self.pk).count()
return glosses_with_this_lemma


class LemmaIdglossTranslation(models.Model):
"""A Lemma ID Gloss"""
Expand Down
34 changes: 19 additions & 15 deletions signbank/dictionary/templates/dictionary/admin_lemma_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
var csrf_token = '{{csrf_token}}';
var page_number = {{ page_number }};
var paginate_by = '{{paginate_by}}';
var page_number = {{page_obj.number}};
var populate_fields_keys = {{populate_fields_keys|safe}};
var populate_fields = {{populate_fields|safe}};

Expand Down Expand Up @@ -220,7 +221,7 @@ <h3>{% trans "Lemmas" %}</h3>
</form>


{% if search_results %}
{% if object_list %}

<table class='table table-condensed'>
<thead>
Expand All @@ -234,7 +235,7 @@ <h3>{% trans "Lemmas" %}</h3>
</tr>
</thead>
<tbody>
{% for lemma in search_results %}
{% for lemma in object_list %}
<tr>
{% if SHOW_DATASET_INTERFACE_OPTIONS %}
<td>
Expand Down Expand Up @@ -276,38 +277,41 @@ <h3>{% trans "Lemmas" %}</h3>

<ul class='pagination pagination-sm'>
{% if page_obj.has_previous %}
<li><a href="?page={{ page_obj.previous_page_number }}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">&laquo;</a></li>
<li><a href="?page={{page_obj.previous_page_number}}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{key}}={{value}}{% endif %}{% endfor %}">&laquo;</a></li>
{% endif %}

{% if page_obj.number > 10 %}
<li><a>...</a></li>
{% endif %}

{% for p in page_obj.paginator.page_range %}

{% if p < page_obj.number|add:"10" and p > page_obj.number|add:"-10" %}
<li {% if p == page_obj.number %}class='active'{% endif %}>
<a href='?page={{ p }}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}'>{% if p == 0 %}Start{% else %}{{p}}{% endif %}</a>
{% if p < page_obj.number|add:"10" and p > page_obj.number|add:"-10" %}
{% if p == page_obj.number %}
<li class='active'>
<a href="?page={{p}}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{key}}={{value}}{% endif %}{% endfor %}">{{p}}</a>
</li>
{% else %}
<li>
<a href="?page={{p}}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{key}}={{value}}{% endif %}{% endfor %}">{{p}}</a>
</li>
{% endif %}
{% endif %}
{% endif %}

{% endfor %}

{% if page_obj.paginator.num_pages > page_obj.number|add:"10" %}
{% if page_obj.paginator.num_pages > page_obj.number|add:10 %}
<li><a>...</a></li>
<li>
<a href='?page={{ page_obj.paginator.num_pages }}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}'>{{page_obj.paginator.num_pages}}</a>
<a href="?page={{page_obj.paginator.num_pages}}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{key}}={{value}}{% endif %}{% endfor %}">{{page_obj.paginator.num_pages}}</a>
</li>
{% endif %}

{% if page_obj.has_next %}
<li><a href="?page={{ page_obj.next_page_number }}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{ key }}={{ value }}{% endif %}{% endfor %}">&raquo;</a></li>


</ul>
<li><a href="?page={{page_obj.next_page_number}}{% for key,value in request.GET.items %}{% if key != 'page' %}&{{key}}={{value}}{% endif %}{% endfor %}">&raquo;</a></li>
{% endif %}

</ul>

{% endif %}
</span>
</div>
{% endif %}
Expand Down
27 changes: 18 additions & 9 deletions signbank/dictionary/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -1491,15 +1491,15 @@ def test_QueryLemmasWithoutGlosses(self):

# search for the lemma without glosses: test_lemma_without_gloss
response = client.get('/dictionary/lemma/?lemma_en=without', follow=True)
self.assertEqual(len(response.context['search_results']), 1)
self.assertEqual(len(response.context['object_list']), 1)

# Search lemmas with no glosses (no_glosses=1 is set to true aka 1), there are 2
response = client.get('/dictionary/lemma/?no_glosses=1', follow=True)
self.assertEqual(len(response.context['search_results']), 2)
self.assertEqual(len(response.context['object_list']), 2)

# Search lemmas that have glosses, there is only one
response = client.get('/dictionary/lemma/?has_glosses=1', follow=True)
self.assertEqual(len(response.context['search_results']), 1)
self.assertEqual(len(response.context['object_list']), 1)

response = client.post('/dictionary/lemma/', {'delete_lemmas': 'confirmed'}, follow=True)

Expand All @@ -1521,23 +1521,32 @@ def test_QueryLemmasWithoutGlosses(self):
self.assertEqual(response.status_code,200)

response = client.get('/dictionary/lemma/?lemma_en=without', follow=True)
self.assertEqual(len(response.context['search_results']), 0)
self.assertEqual(len(response.context['object_list']), 0)

response = client.get('/dictionary/lemma/?lemma_en=does_not_match', follow=True)
self.assertEqual(len(response.context['search_results']), 1)
self.assertEqual(len(response.context['object_list']), 1)

# delete the remaining lemma without glosses
response = client.post('/lemmas/show_all/', {'delete_lemmas': 'delete_lemmas'}, follow=True)
self.assertEqual(response.status_code, 200)

response = client.get('/dictionary/lemma/?no_glosses=1', follow=True)
self.assertEqual(len(response.context['search_results']), 0)
all_glosses = Gloss.objects.all()
print('LemmaTests glosses after deleting lemmas: ', all_glosses)

all_lemmas = LemmaIdgloss.objects.all()
print('LemmaTests lemmas after delete: ', all_lemmas)

all_lemma_translations = LemmaIdglossTranslation.objects.all()
print('LemmaTests translations after delete: ', all_lemma_translations)
lemmas_without_glosses = []
lemmas_with_glosses = []
for lem in all_lemmas:
number_of_glosses = all_glosses.filter(lemma=lem).count()
if number_of_glosses > 0:
lemmas_with_glosses.append(lem)
else:
lemmas_without_glosses.append(lem)

print('Lemmas without glosses: ', lemmas_without_glosses)
self.assertEqual(len(lemmas_without_glosses), 1)


class HandshapeTests(TestCase):
Expand Down

0 comments on commit 879e5d6

Please sign in to comment.