Want to sort data by names, but unfortunately there are many data with leading whitespaces, that is why rest_framework.filters.OrderingFilter
doesn't work properly. Mongo, DRF are used in my project.
My model:
from mongoengine import DynamicDocument, fields
class Book(DynamicDocument):
name = fields.StringField(required=True)
description = fields.StringField(blank=True, null=True)
meta = {
'collection': 'books',
'strict': False,
}
My view:
from rest_framework.filters import OrderingFilter
from rest_framework_mongoengine import viewsets
from core.serializers import BookSerializer
from core.models import Book
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializer
queryset = Book.objects.all()
filter_backends = [OrderingFilter]
ordering_fields = ['name']
ordering = ['name']
Someone has any idea, how to solve that?
CodePudding user response:
There is aggregation operation called $trim in mongoDB that you can use to sanitize the string data , if you want to remove only the leading spaces then you can use the $ltrim ...
CodePudding user response:
If someone deals with mongoengine
, you can solve this problem with queryset.aggregate()
:
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializer
queryset = Book.objects.all()
def get_queryset(self):
queryset = self.queryset
pipeline = [
{
'$project': {
'id': {'$toString': '$_id'},
'name': 1,
'ltrim_lower_name': {'$ltrim': {'input': {'$toLower': '$name'}}},
'description': 1,
}
},
{'$sort': {'ltrim_lower_name': 1}}
]
return queryset.aggregate(pipeline)
Used python 'trim_lower_name': {'$ltrim': {'input': {'$toLower': '$name'}}}
because need case-insensitive sorting.