Commit ace40b01 authored by Rémi Duraffort's avatar Rémi Duraffort
Browse files

Generate less database queries

In fact, num_devices_visible_to is too complex and generates many queryes for
most use cases.

Change-Id: I5dd47e0437af5e80cbb7d931ddc72e507ef6d19b
parent 7fcbd7c6
......@@ -306,7 +306,7 @@ class SchedulerAPI(ExposedAPI):
keys = ['busy', 'idle', 'offline']
for dev_type in DeviceType.objects.all():
if dev_type.num_devices_visible_to(self.user) == 0:
if not dev_type.some_devices_visible_to(self.user):
continue
device_type_names.append(dev_type.name)
......@@ -734,7 +734,7 @@ class SchedulerAPI(ExposedAPI):
continue
if device_type.owners_only:
# do the more expensive check second and only for a hidden device type
if device_type.num_devices_visible_to(self.user) == 0:
if not device_type.some_devices_visible_to(self.user):
continue
job_status[str(job.display_id)] = job.get_status_display()
return job_status
......
......@@ -385,6 +385,22 @@ class DeviceType(models.Model):
else:
return devices.count()
def some_devices_visible_to(self, user):
"""
:param user: User to check
:return: True if some devices of this DeviceType are visible
"""
devices = Device.objects.filter(device_type=self) \
.only('user', 'group') \
.select_related('user', 'group')
if self.owners_only:
for d in devices:
if d.is_owned_by(user):
return True
return False
else:
return devices.exists()
class DefaultDeviceOwner(models.Model):
"""
......@@ -793,7 +809,7 @@ class Device(RestrictedResource):
if self.device_type.owners_only:
if not user:
return False
if self.device_type.num_devices_visible_to(user) == 0:
if not self.device_type.some_devices_visible_to(user):
return False
if not self.is_public:
if not user:
......@@ -1170,7 +1186,7 @@ def _get_device_type(user, name):
msg = "Device type '%s' is unavailable. %s" % (name, e)
logger.error(msg)
raise DevicesUnavailableException(msg)
if device_type.num_devices_visible_to(user) == 0:
if not device_type.some_devices_visible_to(user):
msg = "Device type '%s' is unavailable to user '%s'" % (name, user.username)
logger.error(msg)
raise DevicesUnavailableException(msg)
......@@ -2320,7 +2336,7 @@ class TestJob(RestrictedResource):
return True
device_type = self.job_device_type()
if device_type and device_type.owners_only:
if device_type.num_devices_visible_to(user) == 0:
if not device_type.some_devices_visible_to(user):
return False
if self.is_public:
return True
......
......@@ -175,7 +175,7 @@ class JobTable(LavaTable):
return 'connection'
else:
return '-'
if device_type.num_devices_visible_to(self.context.get('request').user) == 0:
if not device_type.some_devices_visible_to(self.context.get('request').user):
return "Unavailable"
return retval
......
......@@ -649,7 +649,7 @@ def filter_device_types(user):
"""
visible = []
for device_type in DeviceType.objects.filter(display=True).only('name', 'owners_only'):
if device_type.num_devices_visible_to(user) > 0:
if device_type.some_devices_visible_to(user):
visible.append(device_type.name)
return visible
......@@ -697,7 +697,7 @@ def device_type_detail(request, pk):
raise Http404()
# Check that at least one device is visible to the current user
if dt.owners_only:
if dt.num_devices_visible_to(request.user) == 0:
if not dt.some_devices_visible_to(request.user):
raise Http404('No device type matches the given query.')
# Get some test job statistics
......@@ -2199,8 +2199,8 @@ def edit_transition(request):
def transition_detail(request, pk):
transition = get_object_or_404(DeviceStateTransition, id=pk)
device_type = transition.device.device_type
if device_type.num_devices_visible_to(request.user) == 0:
raise Http404()
if not device_type.some_devices_visible_to(request.user):
raise Http404('No device type matches the given query.')
trans_data = TransitionView(request, transition.device, model=DeviceStateTransition, table_class=DeviceTransitionTable)
trans_table = DeviceTransitionTable(trans_data.get_table_data())
config = RequestConfig(request, paginate={"per_page": trans_table.length})
......@@ -2326,12 +2326,12 @@ def device_detail(request, pk):
try:
device = Device.objects.select_related('device_type', 'user').get(pk=pk)
except Device.DoesNotExist:
raise Http404()
raise Http404('No device matches the given query.')
# Any user that can access to a device_type can
# see all the devices even if they are for owners_only
if device.device_type.owners_only:
if device.device_type.num_devices_visible_to(request.user) == 0:
if not device.device_type.some_devices_visible_to(request.user):
raise Http404('No device matches the given query.')
# Find previous and next device
......@@ -2446,12 +2446,12 @@ def device_dictionary(request, pk):
try:
device = Device.objects.select_related('device_type', 'user').get(pk=pk)
except Device.DoesNotExist:
raise Http404()
raise Http404('No device matches the given query.')
# Any user that can access to a device_type can
# see all the devices even if they are for owners_only
if device.device_type.owners_only:
if device.device_type.num_devices_visible_to(request.user) == 0:
if not device.device_type.some_devices_visible_to(request.user):
raise Http404('No device matches the given query.')
if not device.is_pipeline:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment