Как удалить похожие и дублирующиеся запросы в django rest framework?

Когда я вызываю конечную точку продукта, происходят дублирующие и похожие запросы для среднего рейтинга. Я использовал prefetch_related для решения этой проблемы, но кажется, что использованный мной способ не является правильный. Помогите мне, пожалуйста, решить эту проблему.

Вот структура модели

models.py

class Product(models.Model):
    name = models.CharField(max_length=255)
    vendor = models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE,
    )

class ProductRating(models.Model):
    product_id = models.ForeignKey(
        Product,
        on_delete=models.CASCADE,
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    maxval=5
    message='Rating must be less than 5'
    rate =models.PositiveIntegerField(validators=[MaxValueValidator(maxval,message)],null=True)
    comment = models.TextField(blank=True,null=True)
    seller_reply = models.TextField(blank=True,null=True)
    reply_at=models.DateTimeField(auto_now=True)
    created_at=models.DateTimeField(auto_now=False,auto_now_add=True)

class VendorRating(models.Model):
    product_id = models.ForeignKey(
        Product,
        on_delete=models.CASCADE,
    )
    vendor_id=models.ForeignKey(
        Vendor,
        on_delete=models.CASCADE
    )
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    maxval=5
    message='Rating must be less than 5'
    communication_rate=models.PositiveIntegerField(validators=[MaxValueValidator(maxval,message)],null=True,blank=True)
    product_quality_rate=models.PositiveIntegerField(validators=[MaxValueValidator(maxval,message)],null=True,blank=True)
    experience_rate=models.PositiveIntegerField(validators=[MaxValueValidator(maxval,message)],null=True,blank=True)
    created_at=models.DateTimeField(auto_now=False,auto_now_add=True)

в файле views.py

def get_queryset(self):
        queryset=self.get_serializer().setup_eager_loading(Product.objects.all())
        return queryset

в serializers.py

class ProductSerializer(TaggitSerializer, serializers.ModelSerializer):
      avg_productrating = serializers.SerializerMethodField("get_rating")
   avg_vendorrating=serializers.SerializerMethodField("get_avgvendorrating")

     def get_rating(self, obj):
        rating=obj.productrating_set.all().aggregate(avg=Avg("rate"))['avg']
        average_rate=round(rating,2) if rating else rating
        return average_rate

      def get_avgvendorrating(self,obj):
        try:
            average_rate=obj.vendor.vendorrating_set.all().aggregate(
                Avg("communication_rate"),Avg('product_quality_rate'),Avg("experience_rate")
            )
            rates=[rate for rate in average_rate.values() if rate is not None]
            if(not rates):
                total=0
            else:
                total=sum(rates)/3

            return round(total,2)
        except:
            return 0

      


    @staticmethod
    def setup_eager_loading(queryset):
        """ Perform necessary eager loading of data. """
        queryset=queryset.prefetch_related(Prefetch('vendor',queryset=Vendor.objects.prefetch_related('user','vendorrating_set')))  
 

в urls.py

rom rest_framework import routers
from . import views

router = routers.SimpleRouter()
router.register(r"product", views.ProductViewSet,basename='products')

вывод в debug-tools

SELECT AVG("buysell_productrating"."rate") AS "avg"
  FROM "buysell_productrating"
 WHERE "buysell_productrating"."product_id_id" = '3' 3 similar queries.

SELECT AVG("buysell_vendorrating"."communication_rate") AS "communication_rate__avg",
       AVG("buysell_vendorrating"."product_quality_rate") AS "product_quality_rate__avg",
       AVG("buysell_vendorrating"."experience_rate") AS "experience_rate__avg"
  FROM "buysell_vendorrating"
 WHERE "buysell_vendorrating"."vendor_id_id" = '1' 3 similar queries.  Duplicated 2 times.

Вернуться на верх