Home > OS >  How to trim/strip leading whitespaces from StringField for list view in Django/Mongodb?
How to trim/strip leading whitespaces from StringField for list view in Django/Mongodb?

Time:03-31

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.

  • Related