tags:

views:

30

answers:

2

I have the following model:

class Artist(models.Model):
    cell_phone = models.CharField(20)
    pr_phone = modelsCharField(20)

In my template, I can search for all artists for whom the entered phone number match their cell phone or PR phone. Assuming there are no restrictions on how the phone numbers have been initially entered, that is phone number can be stored in any of the following formats:

123 456 7890
(123) 456-7890
123-456-7890

The brute force way to do it is:

# variable input_phone has already been stripped of dashes, braces and spaces
all_artists = Artists.objects.all()
artists = []

for artist in all_artists:
    cell_phone = artist.cell_phone
    pr_phone = artist.pr_phone

    if cell_phone.find(input_phone) >= 0 or pr_phone.find(pr_phone) >= 0:
        artists.append(artist)

return artists

I'm using find because I can also search for all artists who live within a specific area code. Is there another way to the above through Django's query filter?

A: 

I think the best way to do this would be to use the django Q object (http://docs.djangoproject.com/en/1.1/topics/db/queries/#complex-lookups-with-q-objects)

So I believe this code would work for you:

from django.db.models import Q
Artists.objects.filter(Q(cell_phone=input_phone) | Q(pr_phone=input_phone))

It should return all Artists that have a cell phone or pr phone number that matches input_phone.

BenMills
How do you handle the case where the cell_phone in the DB is 123-456-7890 but the entered phone number to search is (123) 456-7890? There can be more of those cases where the cell_phone in the DB could be 123 456 7890.
Thierry Lam
You would probably want to use __contains (http://docs.djangoproject.com/en/1.1/ref/models/querysets/#contains) So: Q(cell_phone__contains =input_phone) | Q(pr_phone__contains =input_phone)
BenMills
Contains is SQL LIKE. SQL LIKE doesn't know how to strip out special chars like (, ), - or empty char. I basically want to strip out those special chars from the phone column in the database and also from the search input phone.
Thierry Lam
Then I think the best way to move forward would be to process the input to make sure it is only numbers.
BenMills
+1  A: 

This issue is very similar to relative dates handling. Basically, you need to have two fields: one for user's display (123)-456-789 whatever, and one for internal use, stripped and cleaned out to 12345678. Then querying any number is not a problem, __contains should work just right.

Yes - this is doubles amount of data (while for phone number i think it's negligible), but it's totally worth it.

Dmitry Shevchenko