optimze home page and product page
This commit is contained in:
@@ -11,6 +11,10 @@ from django.utils.html import format_html
|
||||
from unfold.decorators import display
|
||||
from utils.admin import ModelAdmin
|
||||
from unfold.contrib.filters.admin import ChoicesDropdownFilter
|
||||
from django.core.cache import cache
|
||||
|
||||
# Cache key for home page
|
||||
HOME_CACHE_KEY = 'home_view_data_anonymous'
|
||||
|
||||
|
||||
@admin.register(ShowCaseSlider)
|
||||
@@ -27,6 +31,10 @@ class ShowCaseSliderAdmin(ModelAdmin, ImportExportModelAdmin):
|
||||
"widget": ArrayWidget,
|
||||
}
|
||||
}
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
super().save_model(request, obj, form, change)
|
||||
cache.delete(HOME_CACHE_KEY)
|
||||
|
||||
@admin.register(LearnVideoModel)
|
||||
class LearnVideoAdmin(UnfoldModelAdmin):
|
||||
@@ -49,6 +57,10 @@ class LearnVideoAdmin(UnfoldModelAdmin):
|
||||
def has_add_permission(self, request, obj=None):
|
||||
return request.user.video_uploader
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
super().save_model(request, obj, form, change)
|
||||
cache.delete(HOME_CACHE_KEY)
|
||||
|
||||
|
||||
@display(description='دیده شده')
|
||||
def display_viewd(self, instance):
|
||||
@@ -78,6 +90,10 @@ class SliderAdmin(ModelAdmin, ImportExportModelAdmin):
|
||||
"widget": ArrayWidget,
|
||||
}
|
||||
}
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
super().save_model(request, obj, form, change)
|
||||
cache.delete(HOME_CACHE_KEY)
|
||||
|
||||
@admin.register(HomeImageModel)
|
||||
class HomeImageAdmin(ModelAdmin, ImportExportModelAdmin):
|
||||
@@ -93,6 +109,10 @@ class HomeImageAdmin(ModelAdmin, ImportExportModelAdmin):
|
||||
"widget": ArrayWidget,
|
||||
}
|
||||
}
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
super().save_model(request, obj, form, change)
|
||||
cache.delete(HOME_CACHE_KEY)
|
||||
|
||||
|
||||
# admin.py
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.2 on 2026-05-04 06:29
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('home', '0018_remove_showcaseslider_image_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='slidermodel',
|
||||
name='id',
|
||||
field=models.BigAutoField(auto_created=True, db_index=True, primary_key=True, serialize=False, verbose_name='ID'),
|
||||
),
|
||||
]
|
||||
@@ -2,6 +2,7 @@ from django.db import models
|
||||
from django.urls import reverse
|
||||
|
||||
class SliderModel(models.Model):
|
||||
id = models.BigAutoField(auto_created=True, db_index=True, primary_key=True, serialize=False, verbose_name='ID')
|
||||
link = models.URLField(verbose_name='لینک')
|
||||
title = models.CharField(max_length=50, verbose_name='عنوان')
|
||||
description = models.TextField(verbose_name='توضیحات')
|
||||
|
||||
+76
-14
@@ -1,11 +1,13 @@
|
||||
from django.shortcuts import render, get_object_or_404, redirect
|
||||
from rest_framework.views import APIView, Response
|
||||
from product.models import ProductModel, SubCategoryModel, MainCategoryModel
|
||||
from product.models import ProductModel, SubCategoryModel, MainCategoryModel, ProductVariant
|
||||
from product.serializers import SubCategorySerializer, DynamicProductSerializer, MainCategorySerializer
|
||||
from .serializers import *
|
||||
from .models import *
|
||||
from rest_framework import status
|
||||
from django.views import View
|
||||
from django.db.models import Prefetch
|
||||
from django.core.cache import cache
|
||||
|
||||
|
||||
class ChangeViewVideo(View):
|
||||
@@ -18,31 +20,87 @@ class ChangeViewVideo(View):
|
||||
|
||||
class HomeView(APIView):
|
||||
authentication_classes = []
|
||||
|
||||
def get(self, request):
|
||||
# Check cache first for anonymous users
|
||||
cache_key = 'home_view_data_anonymous'
|
||||
if not request.user.is_authenticated:
|
||||
cached_data = cache.get(cache_key)
|
||||
if cached_data:
|
||||
return Response(cached_data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
sliders = SliderModel.objects.all()
|
||||
sliders = SliderModel.objects.only('id', 'link', 'title', 'description', 'image', 'video')[:10]
|
||||
slider_ser = SliderSerializer(instance=sliders, many=True, context={'request': request})
|
||||
|
||||
main_categories = MainCategoryModel.objects.filter(show_in_home=True)
|
||||
main_categories = MainCategoryModel.objects.filter(
|
||||
show_in_home=True
|
||||
).prefetch_related('subcategorys')
|
||||
main_category_ser = MainCategorySerializer(instance=main_categories, many=True, context={'request': request})
|
||||
|
||||
top_seller_products = ProductModel.objects.filter(show_in_top_seller=True)
|
||||
top_seller_products_ser = DynamicProductSerializer(instance=top_seller_products, many=True, context={'request': request, 'view_type': 'list'})
|
||||
# Optimize variant prefetching - prefetch all variants, limit applied in serializer
|
||||
variant_prefetch = Prefetch(
|
||||
'variants',
|
||||
ProductVariant.objects.prefetch_related('images').order_by('-discount', 'price')
|
||||
)
|
||||
|
||||
lot_of_discount_products = ProductModel.objects.filter(show_in_lot_of_discount=True)
|
||||
lot_of_discount_products_ser = DynamicProductSerializer(instance=lot_of_discount_products, many=True, context={'request': request, 'view_type': 'list'})
|
||||
# Top seller products
|
||||
top_seller_products = ProductModel.objects.filter(
|
||||
show_in_top_seller=True
|
||||
).select_related('category', 'shop').prefetch_related(
|
||||
variant_prefetch
|
||||
).only('id', 'name', 'image', 'rating', 'slug', 'category', 'shop')[:20]
|
||||
top_seller_products_ser = DynamicProductSerializer(
|
||||
instance=top_seller_products,
|
||||
many=True,
|
||||
context={'request': request, 'view_type': 'list'}
|
||||
)
|
||||
|
||||
most_viewed_products = ProductModel.objects.filter(show_in_most_viewed=True)
|
||||
most_viewed_products_ser = DynamicProductSerializer(instance=most_viewed_products, many=True, context={'request': request, 'view_type': 'list'})
|
||||
# Lot of discount products
|
||||
lot_of_discount_products = ProductModel.objects.filter(
|
||||
show_in_lot_of_discount=True
|
||||
).select_related('category', 'shop').prefetch_related(
|
||||
variant_prefetch
|
||||
).only('id', 'name', 'image', 'rating', 'slug', 'category', 'shop')[:20]
|
||||
lot_of_discount_products_ser = DynamicProductSerializer(
|
||||
instance=lot_of_discount_products,
|
||||
many=True,
|
||||
context={'request': request, 'view_type': 'list'}
|
||||
)
|
||||
|
||||
trends_products = ProductModel.objects.filter(show_in_trends=True)
|
||||
trends_products_ser = DynamicProductSerializer(instance=trends_products, many=True, context={'request': request, 'view_type': 'list'})
|
||||
# Most viewed products
|
||||
most_viewed_products = ProductModel.objects.filter(
|
||||
show_in_most_viewed=True
|
||||
).select_related('category', 'shop').prefetch_related(
|
||||
variant_prefetch
|
||||
).only('id', 'name', 'image', 'rating', 'slug', 'category', 'shop')[:20]
|
||||
most_viewed_products_ser = DynamicProductSerializer(
|
||||
instance=most_viewed_products,
|
||||
many=True,
|
||||
context={'request': request, 'view_type': 'list'}
|
||||
)
|
||||
|
||||
home_image = HomeImageModel.objects.all().first()
|
||||
# Trends products
|
||||
trends_products = ProductModel.objects.filter(
|
||||
show_in_trends=True
|
||||
).select_related('category', 'shop').prefetch_related(
|
||||
variant_prefetch
|
||||
).only('id', 'name', 'image', 'rating', 'slug', 'category', 'shop')[:20]
|
||||
trends_products_ser = DynamicProductSerializer(
|
||||
instance=trends_products,
|
||||
many=True,
|
||||
context={'request': request, 'view_type': 'list'}
|
||||
)
|
||||
|
||||
home_image = HomeImageModel.objects.only(
|
||||
'id', 'image1', 'image2', 'title1', 'title2',
|
||||
'description1', 'description2', 'link1', 'link2',
|
||||
'video1', 'video2'
|
||||
).first()
|
||||
home_image_ser = HomeImageSerializer(instance=home_image, context={'request': request})
|
||||
|
||||
show_cases = ShowCaseSlider.objects.all()
|
||||
show_cases = ShowCaseSlider.objects.only(
|
||||
'id', 'title', 'description', 'image1', 'image2', 'image3', 'background_image'
|
||||
)[:10]
|
||||
show_cases_ser = ShowCaseSliderSerialzier(instance=show_cases, many=True, context={'request': request})
|
||||
|
||||
response = {
|
||||
@@ -57,4 +115,8 @@ class HomeView(APIView):
|
||||
'show_case_slider': show_cases_ser.data
|
||||
}
|
||||
|
||||
# Cache for anonymous users only (avoid issues with user-specific data)
|
||||
if not request.user.is_authenticated:
|
||||
cache.set(cache_key, response, 60 * 5) # 5 minutes cache
|
||||
|
||||
return Response(response, status=status.HTTP_200_OK)
|
||||
Reference in New Issue
Block a user