Home > Blockchain >  Django queryset searching for firstname and lastname with startswith
Django queryset searching for firstname and lastname with startswith

Time:11-18

I have one django app, In which I search for a name from first_name and last_name. Which is working for me using Q tag.

from django.db.models import Q 

def find_user_by_name(query_name):
   qs = User.objects.all()
   for term in query_name.split():
     qs = qs.filter( Q(first_name__icontains = term) | Q(last_name__icontains = term))
   return qs

But I'm facing one issue regarding ordering the data not coming as I want.

For example: search_word = 'Kia' The result I got after the search is:

        {
            "first_name": "Katja",
            "last_name": "Tukiainen", 
        },
        {
            "first_name": "Kia",
            "last_name": "Reijonen",
        },
        {
            "first_name": "Sanna",
            "last_name": "Kiander",
        }
    ]

But I want a result in which first starts with Kia first, Result like:

        {
            "first_name": "Kia",
            "last_name": "Reijonen",
        },
        {
            "first_name": "Katja",
            "last_name": "Tukiainen",
            
        },
        {
            "first_name": "Sanna",
            "last_name": "Kiander",
        }
    ]

Please help me regarding this, I try this with startswith but not working for me. Thanks in advance.

CodePudding user response:

You can work with an .union(…) [Django-doc]:

def find_user_by_name(query_name):
    qs = User.objects.all()
    q1 = Q(*[
        Q(('first_name__istartswith', term)) | Q(('last_name__istartswith', term))
        for term in query_name.split()
    ])
    q2 = Q(*[
        Q(('first_name__icontains', term)) | Q(('last_name__icontains', term))
        for term in query_name.split()
    ])
    return qs.filter(q1).union(qs.filter(q2))

CodePudding user response:

first you'll have to RND on django full text search but for now try this.

Add

"django.contrib.postgres",

to your INSTALLED_APPS in settings.py

then use the following search vector and Search Rank

    vector = SearchVector('first_name', weight='A')   SearchVector('last_name', weight='B')
    query = SearchQuery('Kia')
    users =User.objects.annotate(rank=SearchRank(vector, query)). \
        filter(Q(last_name__icontains='Kia') | Q(first_name__icontains='Kia')).order_by('-rank')

Remember to import

from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector

Good luck!

  • Related