diff --git a/tom_targets/models.py b/tom_targets/models.py
index 7acd4947e..6b9d9d59b 100644
--- a/tom_targets/models.py
+++ b/tom_targets/models.py
@@ -172,7 +172,7 @@ class Target(models.Model):
max_length=100, choices=TARGET_TYPES, verbose_name='Target Type', help_text='The type of this target.'
)
created = models.DateTimeField(
- auto_now_add=True, verbose_name='Time Created',
+ auto_now_add=True, verbose_name='Time Created', db_index=True,
help_text='The time which this target was created in the TOM database.'
)
modified = models.DateTimeField(
diff --git a/tom_targets/templates/tom_targets/target_list.html b/tom_targets/templates/tom_targets/target_list.html
index b336e54c4..6fc90584e 100644
--- a/tom_targets/templates/tom_targets/target_list.html
+++ b/tom_targets/templates/tom_targets/target_list.html
@@ -23,7 +23,7 @@
{% select_target_js %}
- {% target_distribution filter.qs %}
+ {% target_distribution object_list %}
{% bootstrap_pagination page_obj extra=request.GET.urlencode %}
diff --git a/tom_targets/templatetags/targets_extras.py b/tom_targets/templatetags/targets_extras.py
index d5c8a40b1..b1f491717 100644
--- a/tom_targets/templatetags/targets_extras.py
+++ b/tom_targets/templatetags/targets_extras.py
@@ -8,6 +8,8 @@
from django.conf import settings
from django.db.models import Q
from guardian.shortcuts import get_objects_for_user
+from guardian.models import GroupObjectPermission
+from guardian.core import ObjectPermissionChecker
import numpy as np
from plotly import offline
from plotly import graph_objs as go
@@ -24,8 +26,28 @@ def recent_targets(context, limit=10):
"""
Displays a list of the most recently created targets in the TOM up to the given limit, or 10 if not specified.
"""
+ # Get User and group permissions for user
user = context['request'].user
- return {'targets': get_objects_for_user(user, 'tom_targets.view_target').order_by('-created')[:limit]}
+ groups = user.groups.all()
+ group_permissions = GroupObjectPermission.objects.filter(group__in=groups, permission__codename='view_target')
+
+ # Build Query for the most recently created objects
+ target_query = Target.objects.order_by('-created').prefetch_related()[:limit]
+
+ # Build permission checker and check if user has permission to view each target
+ checker = ObjectPermissionChecker(user)
+ checker.prefetch_perms(target_query)
+ targets = [target for target in target_query if checker.has_perm('view_target', target)]
+
+ if targets:
+ # If any of these targets are viewable, display them
+ return {'targets': targets}
+ elif group_permissions.count():
+ # Otherwise, if user has permission to view ANY target, find them. (EXPENSIVE)
+ return {'targets': get_objects_for_user(user, 'tom_targets.view_target').order_by('-created')[:limit]}
+ else:
+ # Return empty list if user has no permissions.
+ return {'targets': []}
@register.inclusion_tag('tom_targets/partials/recently_updated_targets.html', takes_context=True)
@@ -225,7 +247,7 @@ def target_distribution(targets):
"""
Displays a plot showing on a map the locations of all sidereal targets in the TOM.
"""
- locations = targets.filter(type=Target.SIDEREAL).values_list('ra', 'dec', 'name')
+ locations = targets.values_list('ra', 'dec', 'name')
data = [
dict(
lon=[location[0] for location in locations],
@@ -315,4 +337,8 @@ def target_table(targets):
Returns a partial for a table of targets, used in the target_list.html template
by default
"""
+ # Prefetch related tables to speed up target List Load
+ related_tables = ['aliases', 'dataproduct_set', 'observationrecord_set']
+ for table in related_tables:
+ targets = targets.prefetch_related(table)
return {'targets': targets}
diff --git a/tom_targets/views.py b/tom_targets/views.py
index 500c1e472..9bf6e89e4 100644
--- a/tom_targets/views.py
+++ b/tom_targets/views.py
@@ -50,7 +50,7 @@ class TargetListView(PermissionListMixin, FilterView):
View for listing targets in the TOM. Only shows targets that the user is authorized to view. Requires authorization.
"""
template_name = 'tom_targets/target_list.html'
- paginate_by = 25
+ paginate_by = 10
strict = False
model = Target
filterset_class = TargetFilter