Skip to content

Commit

Permalink
Try to reduce DB trips when displaying the user's order history
Browse files Browse the repository at this point in the history
  • Loading branch information
earlinn committed Dec 25, 2023
1 parent 3adb83a commit 695c524
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 21 deletions.
19 changes: 19 additions & 0 deletions backend/api/orders_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,25 @@ class Meta:
)
model = Order

# TODO: commented code doesn't reduce DB hits
@classmethod
def setup_eager_loading(cls, queryset):
"""Perform necessary eager loading of orders data."""
return queryset.select_related("user")
# ).prefetch_related(
# Prefetch(
# "products",
# queryset=Product.objects.select_related(
# "category", "subcategory", "producer"
# ).prefetch_related(
# "components",
# "tags",
# "promotions",
# "reviews",
# ),
# )
# )


class OrderGetAnonSerializer(serializers.ModelSerializer):
"""Serializer for anonimous user order representation."""
Expand Down
16 changes: 3 additions & 13 deletions backend/api/orders_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from django.conf import settings
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import PermissionDenied
from django.db.models import Prefetch
from django.utils.decorators import method_decorator
from drf_standardized_errors.openapi_serializers import (
ErrorResponse401Serializer,
Expand Down Expand Up @@ -209,7 +208,7 @@ class OrderViewSet(
):
"""Viewset for Order."""

queryset = Order.objects.all()
queryset = OrderGetAuthSerializer.setup_eager_loading(Order.objects.all())
permission_classes = [AllowAny]

def get_serializer_class(self):
Expand Down Expand Up @@ -267,17 +266,8 @@ def retrieve(self, request, **kwargs):

def list(self, request, **kwargs):
if self.request.user.is_authenticated:
queryset = (
Order.objects.select_related("user", "address", "delivery_point")
.prefetch_related(
Prefetch(
"products",
queryset=Product.objects.prefetch_related("promotions"),
)
)
.filter(user=self.request.user)
)
serializer = self.get_serializer(queryset, many=True)
queryset = self.get_queryset().filter(user=self.request.user)
serializer = self.get_serializer(queryset, many=True) # similar DB hits
return Response(serializer.data, status=status.HTTP_200_OK)
return Response(
{"errors": METHOD_ERROR_MESSAGE},
Expand Down
2 changes: 1 addition & 1 deletion backend/api/products_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ class Meta:

@classmethod
def setup_eager_loading(cls, queryset, user):
"""Perform necessary eager loading of product data."""
"""Perform necessary eager loading of products data."""
if user.is_anonymous:
queryset = (
queryset.select_related("category", "subcategory", "producer")
Expand Down
9 changes: 2 additions & 7 deletions backend/api/products_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -522,13 +522,8 @@ def get_serializer_class(self):
return ProductSerializer

def get_queryset(self):
return (
ProductSerializer.setup_eager_loading(
Product.objects.all(), self.request.user
)
# Product.objects.select_related("category", "subcategory", "producer")
# .prefetch_related("components", "tags", "promotions", "reviews")
# .annotate(rating=Avg("reviews__score"))
return ProductSerializer.setup_eager_loading(
Product.objects.all(), self.request.user
)

@transaction.atomic
Expand Down
1 change: 1 addition & 0 deletions backend/api/recipes_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ def get_need_to_buy(self, obj) -> int:
return ceil(obj.amount / obj.ingredient.amount)


# TODO: make setup_eager_loading cls method
class RecipeSerializer(serializers.ModelSerializer):
"""Serializer for recipe representation."""

Expand Down

0 comments on commit 695c524

Please sign in to comment.