Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions django_forest/resources/associations/views/csv.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import csv
import time

from django_forest.resources.associations.utils import AssociationView
from django_forest.resources.utils.csv import CsvMixin
Expand All @@ -13,6 +14,7 @@

class CsvView(SmartFieldMixin, JsonApiSerializerMixin, CsvMixin, AssociationView):
def get(self, request, pk, association_resource):
t0 = time.time()
try:
association_field = get_association_field(self.Model, association_resource)
except Exception as e:
Expand All @@ -25,15 +27,25 @@ def get(self, request, pk, association_resource):
queryset = getattr(self.Model.objects.get(pk=pk), association_resource).all()

params = request.GET.dict()

t2 = time.time()
# enhance queryset
queryset = self.enhance_queryset(queryset, RelatedModel, params, request, apply_pagination=False)
for _ in queryset[0:1]: # force SQL request execution
pass

t3 = time.time()
logger.warning(f"-- timing enhance_queryset: {(t3 - t2):.2f} seconds")
# handle smart fields
self.handle_smart_fields(queryset, RelatedModel._meta.db_table, parse_qs(params), many=True)

t4 = time.time()
logger.warning(f"-- timing smart fields: {(t4 - t3):.2f} seconds")
# json api serializer
data = self.serialize(queryset, RelatedModel, params)

t5 = time.time()
logger.warning(f"-- timing json api serialization: {(t5 - t4):.2f} seconds")
response = self.csv_response(params['filename'])

field_names_requested = [x for x in params[f'fields[{RelatedModel._meta.db_table}]'].split(',')]
Expand All @@ -42,4 +54,7 @@ def get(self, request, pk, association_resource):
writer = csv.DictWriter(response, fieldnames=field_names_requested)
writer.writerow(dict(zip(field_names_requested, csv_header)))
self.fill_csv(data, writer, params)
t6 = time.time()
logger.warning(f"-- timing csv serialization into response body: {(t6 - t5):.2f} seconds")
logger.warning(f"--- total timing: {(t6 - t0):.2f} seconds")
return response
29 changes: 29 additions & 0 deletions django_forest/resources/utils/queryset/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import re

from .filters import FiltersMixin
from .limit_fields import LimitFieldsMixin
from .pagination import PaginationMixin
from .scope import ScopeMixin
from .search import SearchMixin
from .segment import SegmentMixin
from django_forest.resources.utils.decorators import DecoratorsMixin
from django_forest.utils.schema import Schema


class QuerysetMixin(
Expand All @@ -26,7 +29,33 @@ def filter_queryset(self, queryset, Model, params, request):
queryset = queryset.filter(method(params, Model))
return queryset

def join_relations(self, queryset, Model, params, request):
select_related = set()

collection = Schema.get_collection(Model._meta.db_table)
relations = [
field['field']
for field in collection["fields"]
if field["relationship"] is not None and field["relationship"] in ["BelongsTo", "HasOne"]
]

# scope

# filters

# projection
for key, value in params.items():
if re.search(r"fields\[[^\]]+\]", key):
fields_for = key.split("fields[")[1][:-1]
if fields_for in relations:
select_related.add(fields_for)

return queryset.select_related(*select_related)

def enhance_queryset(self, queryset, Model, params, request, apply_pagination=True):
# perform inner join
queryset = self.join_relations(queryset, Model, params, request)

# scopes + filter + search
queryset = self.filter_queryset(queryset, Model, params, request)

Expand Down