Разница между select_related() и prefetch_related() в django?

Могу ли я использовать prefecth_related для поля внешнего ключа. Я использовал select_related для таблицы, содержащей поля с внешним ключом. Могу ли я вместо этого использовать prefetch? Я работаю над modelviewsets.

models.py

class Category(models.Model):
    category_name=models.CharField(max_length=100)
    active=models.BooleanField(default=True)

    def delete(self):
        self.active=False
        self.save(update_fields=('active',))

    def __str__(self):
        return self.category_name


class Brand(models.Model):
    brand_name=models.CharField(max_length=100)
    active=models.BooleanField(default=True)

    def delete(self):
        self.active=False
        self.save(update_fields=('active',))


    def __str__(self):
        return self.brand_name

class Product(models.Model):
    name=models.CharField(max_length=100)
    price=models.FloatField()
    details=models.TextField()
    category=models.ForeignKey(Category,on_delete=models.CASCADE,related_name='productshavecategory')
    brand=models.ForeignKey(Brand,on_delete=models.CASCADE,related_name='productshavebrand')
    stock=models.PositiveBigIntegerField()
    price_per_amount=models.CharField(max_length=100)
    rating=models.PositiveIntegerField(default=0)
    active=models.BooleanField(default=True)
    Special_offer=models.BooleanField(default=False)
    rating_count=models.PositiveIntegerField(default=0)
    average=models.FloatField(default=0)

    def delete(self):
        self.active=False
        self.save(update_fields=('active',))
    
    def __str__(self):
        return self.name

views.py

class CategoryViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    queryset=Category.objects.filter(active=True)
    serializer_class=CategorySerialaizer

    def list(self, request, *args, **kwargs):
        queryset=Category.objects.filter(active=True)
        if queryset.exists():
            serializer=CategorySerialaizer(queryset,many=True)
            return Response({'status':True,'data':serializer.data,'message':'Category found'})
        else:
            return Response({'status':False,'data':None,'message':'Category not found'})


class BrandViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    queryset=Brand.objects.filter(active=True)
    serializer_class=BrandSerialaizer

    def list(self, request, *args, **kwargs):
        queryset=Brand.objects.filter(active=True)
        if queryset.exists():
            serializer=BrandSerialaizer(queryset,many=True)
            return Response({'status':True,'data':serializer.data,'message':'Brands found'})
        else:
            return Response({'status':False,'data':None,'message':'Brands not found'})
    

class ProductViewset(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    queryset=Product.objects.select_related('category','brand').filter( Q(active=True) & Q(stock__gt=0) )
    serializer_class=ProductSerialaizer
    filter_backends = [DjangoFilterBackend,filters.SearchFilter]
    search_fields = ['name']
    filterset_fields = ['category','brand']

    def list(self, request, *args, **kwargs):
        queryset=Product.objects.select_related('category','brand').filter( Q(active=True) & Q(stock__gt=0) )
        if queryset.exists():
            serializer=ProductSerialaizer(queryset,many=True)
            return Response({'status':True,'data':serializer.data,'message':'Products found'})
        else:
            return Response({'status':False,'data':None,'message':'Products not found'})

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

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