I have written a search api for my website in django rest framework. when you search a name (e.g. "jumanji") there might be more than one result for the search for many reasons. what I want is for the result to be ordered by the "rating" field or "releaseDate" field of the Film model.
here are my codes.
# models.py
class Film(models.Model):
filmID = models.AutoField(primary_key=True)
title = models.CharField(max_length=150)
duration = models.PositiveIntegerField()
typeOf = models.IntegerField(validators=[MaxValueValidator(3), MinValueValidator(1),])
rating = models.FloatField(default=0, validators=[MaxValueValidator(10), MinValueValidator(0),])
releaseDate = models.DateTimeField(null=True)
# serializers.py
class FilmSerializer(serializers.ModelSerializer):
class Meta:
model = Film
fields = [
"filmID", "title", "price", "duration", "typeOf", "numberOfFilminoRatings", "filminoRating", "rating",
"releaseDate", "detailsEn", "salePercentage", "saleExpiration", "posterURL", "posterDirectory",
]
# views.py
'''Override get_search_fields method of SearchFilter'''
class DynamicSearch(filters.SearchFilter,):
def get_search_fields(self,view, request):
return request.GET.getlist('search_fields',[])
'''Override page_size_query_param attribute of PageNumberPagination'''
class CustomizePagination(PageNumberPagination):
page_size_query_param = 'limit'
"""Pagination Handler"""
class PaginationHanlerMixin(object):
@property
def paginator(self):
if not hasattr(self, '_paginator'):
if self.pagination_class is None:
self._paginator =None
else :
self._paginator = self.pagination_class()
else :
pass
return self._paginator
def paginate_queryset(self,queryset):
if self.paginator is None:
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
def get_paginated_response(self,data):
if self.paginator is None:
raise "Paginator is None"
return self.paginator.get_paginated_response(data)
class SearchFilm(APIView,PaginationHanlerMixin):
authentication_classes = ()
permission_classes = (AllowAny,)
def __init__(self,):
APIView.__init__(self)
self.search_class=DynamicSearch
self.pagination_class=CustomizePagination
def filter_queryset(self,queryset):
filterd_queryset=self.search_class().filter_queryset(self.request, queryset ,self)
return filterd_queryset
def get(self, request):
films= Film.objects.all()
filtered_queryset=self.filter_queryset(films)
#Get appropriate results for each page
results=self.paginate_queryset(filtered_queryset)
if(results is not None):
serializer=FilmSerializer(results,many=True)
serializer=self.get_paginated_response(serializer.data)
else :
serializer=FilmSerializer(filtered_queryset,many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
It as simple as using function order_by
to QuerySet
of your films. If you give few options, it will be firstfully ordered by leftmost, then second to the left etc.
films = Film.objects.all().order_by('rating', 'releaseDate')