Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Querying full name in Django

Tags:

python

django

People also ask

What is q in django?

Q object encapsulates a SQL expression in a Python object that can be used in database-related operations. Using Q objects we can make complex queries with less and simple code. For example, this Q object filters whether the question starts wiht 'what': from django.

How to save data in models in django?

Creating objectsTo create an object, instantiate it using keyword arguments to the model class, then call save() to save it to the database. This performs an INSERT SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() . The save() method has no return value.


This question was posted long time ago, but I had the similar problem and find answers here pretty bad. The accepted answer only allows you to find exact match by first_name and last_name. The second answer is a little bit better but still bad because you hit database as much as there was words. Here's my solution that concatenates first_name and last_name annotates it and search in this field:

from django.db.models import Value as V
from django.db.models.functions import Concat   

users = User.objects.annotate(full_name=Concat('first_name', V(' '), 'last_name')).\
                filter(full_name__icontains=query)

For example if the name of the person is John Smith, you can find him by typing john smith, john, smith, hn smi and so on. It hits database only ones. And I think this will be the exact SQL that you wanted in the open post.


Easier:

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

Where query_name could be "John Smith" (but would also retrieve user Smith John if any).


class User( models.Model ):
    first_name = models.CharField( max_length=64 )
    last_name = models.CharField( max_length=64 )
    full_name = models.CharField( max_length=128 )
    def save( self, *args, **kw ):
        self.full_name = '{0} {1}'.format( first_name, last_name )
        super( User, self ).save( *args, **kw )

Unless I'm missing something, you can use python to query your DB like so:

from django.contrib.auth.models import User
x = User.objects.filter(first_name='John', last_name='Smith') 

Edit: To answer your question:

If you need to return 'John Paul Smith' when the user searches for 'John Smith' then you can use 'contains' which translates into a SQL LIKE. If you just need the capacity to store the name 'John Paul' put both names in the first_name column.

User.objects.filter(first_name__contains='John', last_name__contains='Smith') 

This translates to:

SELECT * FROM USERS
WHERE first_name LIKE'%John%' 
AND last_name LIKE'%Smith%'

I used this Query to search firstname, lastname, also the fullname.

It solved my problem.

from django.db.models import Q, F
from django.db.models import Value as V
from django.db.models.functions import Concat 

user_list = models.User.objects.annotate(
                        full_name=Concat('first_name', V(' '), 'last_name')
                    ).filter(   
                        Q(full_name__icontains=keyword) | 
                        Q(first_name__icontains=keyword) | 
                        Q(last_name__icontains=keyword)
                    )