Разница между 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, я получил тот же результат и набор запросов, возвращенных почти в то же время. Является ли это правильным способом?