From 84541569bf30f68f1e880a328966c17cb3e56af7 Mon Sep 17 00:00:00 2001 From: Piero Toffanin Date: Thu, 10 Nov 2016 12:26:04 -0500 Subject: [PATCH] Fixed a performance issue with django's ORM --- app/api/projects.py | 1 - app/api/tasks.py | 11 ++++++----- app/models.py | 2 +- requirements.txt | 4 +++- webodm/settings.py | 3 +++ webodm/urls.py | 10 ++++++++++ 6 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/api/projects.py b/app/api/projects.py index 8bae133a..718791d1 100644 --- a/app/api/projects.py +++ b/app/api/projects.py @@ -6,7 +6,6 @@ from .tasks import TaskIDsSerializer class ProjectSerializer(serializers.ModelSerializer): - owner = serializers.PrimaryKeyRelatedField(queryset=User.objects.all()) tasks = TaskIDsSerializer(many=True) class Meta: diff --git a/app/api/tasks.py b/app/api/tasks.py index d1e01a55..3da58158 100644 --- a/app/api/tasks.py +++ b/app/api/tasks.py @@ -16,6 +16,7 @@ class TaskIDsSerializer(serializers.BaseSerializer): def to_representation(self, obj): return obj.id + class TaskSerializer(serializers.ModelSerializer): project = serializers.PrimaryKeyRelatedField(queryset=models.Project.objects.all()) processing_node = serializers.PrimaryKeyRelatedField(queryset=ProcessingNode.objects.all()) @@ -26,7 +27,7 @@ class TaskSerializer(serializers.ModelSerializer): class Meta: model = models.Task - exclude = ('processing_lock', 'console_output', ) + exclude = ('processing_lock', 'console_output', 'orthophoto', ) def get_and_check_project(request, project_pk, perms=('view_project',)): @@ -48,7 +49,7 @@ class TaskViewSet(viewsets.ViewSet): A task represents a set of images and other input to be sent to a processing node. Once a processing node completes processing, results are stored in the task. """ - queryset = models.Task.objects.all() + queryset = models.Task.objects.all().defer('orthophoto', 'console_output') # We don't use object level permissions on tasks, relying on # project's object permissions instead (but standard model permissions still apply) @@ -157,10 +158,10 @@ class TaskViewSet(viewsets.ViewSet): class TaskTilesBase(APIView): queryset = models.Task.objects.all() - def get_and_check_task(self, request, pk, project_pk): + def get_and_check_task(self, request, pk, project_pk, defer=(None, )): get_and_check_project(request, project_pk) try: - task = self.queryset.get(pk=pk, project=project_pk) + task = self.queryset.defer(*defer).get(pk=pk, project=project_pk) except ObjectDoesNotExist: raise exceptions.NotFound() return task @@ -171,7 +172,7 @@ class TaskTiles(TaskTilesBase): """ Returns a prerendered orthophoto tile for a task """ - task = self.get_and_check_task(request, pk, project_pk) + task = self.get_and_check_task(request, pk, project_pk, ('orthophoto', 'console_output')) tile_path = task.get_tile_path(z, x, y) if os.path.isfile(tile_path): tile = open(tile_path, "rb") diff --git a/app/models.py b/app/models.py index 78374729..3468ddb5 100644 --- a/app/models.py +++ b/app/models.py @@ -41,7 +41,7 @@ class Project(models.Model): return self.name def tasks(self, pk=None): - return Task.objects.filter(project=self); + return Task.objects.filter(project=self).only('id') class Meta: permissions = ( diff --git a/requirements.txt b/requirements.txt index b0629648..92348e1e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,6 +2,7 @@ anyjson==0.3.3 APScheduler==3.2.0 Django==1.10 django-common-helpers==0.8.0 +django-debug-toolbar==1.6 django-filter==0.15.3 django-guardian==1.4.6 django-webpack-loader==0.3.3 @@ -10,13 +11,14 @@ drf-nested-routers==0.11.1 funcsigs==1.0.2 futures==3.0.5 Markdown==2.6.7 -pillow==3.3.1 +Pillow==3.3.1 pip-autoremove==0.9.0 psycopg2==2.6.2 pytz==2016.6.1 requests==2.11.1 rfc3987==1.3.7 six==1.10.0 +sqlparse==0.2.2 strict-rfc3339==0.7 tzlocal==1.3 webcolors==1.5 diff --git a/webodm/settings.py b/webodm/settings.py index 8bdee230..c486b05e 100644 --- a/webodm/settings.py +++ b/webodm/settings.py @@ -25,6 +25,7 @@ SECRET_KEY = 'gmarsutd!fee6_58=6k)2je#o2^&&)ovu1svjg8k^(a!7qa7r&' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True +INTERNAL_IPS = ['127.0.0.1'] ALLOWED_HOSTS = [] @@ -43,11 +44,13 @@ INSTALLED_APPS = [ 'rest_framework', 'rest_framework_nested', 'webpack_loader', +# 'debug_toolbar', 'app', 'nodeodm', ] MIDDLEWARE = [ + # 'debug_toolbar.middleware.DebugToolbarMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', diff --git a/webodm/urls.py b/webodm/urls.py index 8fb14eb0..d195adf7 100644 --- a/webodm/urls.py +++ b/webodm/urls.py @@ -15,6 +15,7 @@ Including another URLconf """ from django.conf.urls import include, url from django.contrib import admin +from . import settings admin.site.site_header = 'WebODM Administration' @@ -23,3 +24,12 @@ urlpatterns = [ url(r'^', include('django.contrib.auth.urls')), url(r'^admin/', admin.site.urls), ] + +if settings.DEBUG: + import debug_toolbar + urlpatterns += [ + url(r'^__debug__/', include(debug_toolbar.urls)), + ] + +#from django.contrib.staticfiles.urls import staticfiles_urlpatterns +#urlpatterns += staticfiles_urlpatterns() \ No newline at end of file