diff --git a/entries/views.py b/entries/views.py index d69fd47df7de846184a42605632d4446d63c52ad..8eb87d97ab4c5bd0fd3270ed780cd27734e1c393 100644 --- a/entries/views.py +++ b/entries/views.py @@ -7,6 +7,7 @@ from itertools import chain, product import simplejson +from django.contrib.auth.models import User from django.contrib.auth.decorators import login_required from django.db.models import Prefetch, Q from django.http import JsonResponse, QueryDict @@ -24,6 +25,7 @@ from semantics.models import Frame, PredefinedSelectionalPreference, SelectivePr from common.decorators import ajax_required, ajax from unifier.models import UnifiedFrame +from users.models import Assignment from .forms import ( EntryForm, @@ -372,9 +374,13 @@ def get_entries(request): linked_ids = set() if request.session['show_linked_entries']: - entries_linked = Entry.objects.filter(subentries__schema_hooks__argument_connections__schema_connections__subentry__entry__in=entries).distinct().exclude(id__in=entries) + entries_linked = Entry.objects.filter(pk__in=( + Entry.objects + .filter(subentries__schema_hooks__argument_connections__schema_connections__subentry__entry__in=entries) + .exclude(id__in=entries) + )).distinct() entries = entries | entries_linked - linked_ids = set(e.id for e in entries_linked) + linked_ids = set(entries_linked.values_list('id', flat=True)) first_index, last_index = scroller_params['start'], scroller_params['start'] + scroller_params['length'] order_field, order_dir = scroller_params['order'] @@ -386,12 +392,39 @@ def get_entries(request): order_field = 'pos__tag' if order_dir == 'desc': order_field = '-' + order_field - entries = entries.order_by(order_field).only('id', 'name', 'status__key', 'pos__tag') + + if restrict_to_user: + # pre-filtering entries for performance reasons + entries = entries.filter(lexical_units__frames__assignments__user=User.objects.get(username=restrict_to_user)) + entries = ( + entries + .order_by(order_field) + .select_related('status', 'pos') + .prefetch_related(Prefetch("assignments", to_attr="_assignments")) + ) if with_lexical_units: - entries = entries.prefetch_related("lexical_units") + entries = entries.prefetch_related( + Prefetch( + "lexical_units", + LexicalUnit.objects.prefetch_related( + Prefetch( + "frames", + Frame.objects + .select_related("slowal_frame_2_unified_frame") + .prefetch_related(Prefetch("assignments", to_attr="_assignments")), + to_attr="_frames", + ) + ) + ) + ) status_names = STATUS() POS_names = POS() - entriesList = list(entries) + + def iter_lexical_units(e): + for lu in e.lexical_units.all(): + lu._frame = lu._frames[0] if lu._frames else None + yield lu + result = { 'draw' : scroller_params['draw'], 'recordsTotal': total, @@ -403,7 +436,7 @@ def get_entries(request): 'status' : status_names[e.status.key], 'POS' : POS_names[e.pos.tag], 'related' : e.id in linked_ids, - 'assignee_username': assignment.user.username if (assignment := e.assignments.first()) else None, + 'assignee_username': e._assignments[0].user.username if e._assignments else None, **( { 'lexical_units': [ @@ -411,16 +444,16 @@ def get_entries(request): 'pk': lu.pk, 'display': str(lu), 'assignee_username': ( - assignment.user.username if (frame := lu.frames.first()) and (assignment := frame.assignments.first()) else None + lu._frame._assignments[0].user.username if lu._frame and lu._frame._assignments else None ), - 'status': frame.status if (frame := lu.frames.first()) else "", - 'unified_frame_id': frame.slowal_frame_2_unified_frame.unified_frame_id if (frame := lu.frames.first()) and hasattr(frame, 'slowal_frame_2_unified_frame') else -1, - } for lu in e.lexical_units.all() + 'status': lu._frame.status if lu._frame else "", + 'unified_frame_id': lu._frame.slowal_frame_2_unified_frame.unified_frame_id if lu._frame and hasattr(lu._frame, 'slowal_frame_2_unified_frame') else -1, + } for lu in iter_lexical_units(e) ] } if with_lexical_units else {} ), - } for e in entriesList[first_index:last_index] + } for e in entries[first_index:last_index] ], }