zentenk
zentenk

Reputation: 2815

django queryset filter question

I have a model I want to filter with a search term, which is usually a name. However in my database first_name and last_name are two separate fields.

e.g.

search_term = 'Will Sm'

db_persons record: first_name = 'Will', last_name = 'Smith'

the search term would be able to retrieve this record.

How can I achieve that?

db_persons.objects.filter(__?__)

UPDATE:

Looking for a way to concatenate fields and querying the concatenated result without raw sql

Upvotes: 3

Views: 2865

Answers (2)

Etienne
Etienne

Reputation: 12590

A simple solution will be to add another field complete_name on your model. On save you will update this field by concatenate first_name and last_name fields without any space (you need to strip all spaces from the concatenation result). Then you will do your query on this field with the search_term but with spaces also stripped.

Simple example to give you the general idea:

class Person(models.Model):
    first_name = CharField(...)
    last_name = CharField(...)
    complete_name = CharField(...)

    def save(self, *args, **kwargs):
        complete_name = '%s%s' % (self.first_name, self.last_name)
        self.complete_name = complete_name.replace(' ', '')
        super(Person, self).save(*args, **kwargs)

results = Person.objects.filter(complete_name__icontains=search_term.replace(' ', ''))

Upvotes: 2

Reto Aebersold
Reto Aebersold

Reputation: 16644

If you want to search in first AND lastname you can simply use:

db_persons.objects.filter(first_name='Will', last_name='Smith')

Use Q objects if you want to search in first_name OR last_name:

from django.db.models.query_utils import Q
db_persons.objects.filter(Q(first_name='will') | Q(last_name='will'))

Update according comment: A simple solution could look like this:

search_string = 'will smith'
query_list = search_string.split()
db_persons.objects.filter(Q(first_name__in=query_list) | Q(last_name__in=query_list))

If you use mysql, you could use search.

Upvotes: 6

Related Questions