2010-12-12 16 views
0

Meine Suchfunktion erhält einen Suchbegriff in eine der folgenden Möglichkeiten:Suche nach mehreren

  • first_name "Thomas"
  • last_name "smith"
  • Vorname Nachname "thomas smith"

Ich versuche, eine Abfrage zu erstellen, die den Client "Thomas" durch einen dieser Begriffe finden wird, wird aber die Ergebnisse auf "Thomas Smith" statt "thom als jones "oder" george smith "wenn beide Namen angegeben sind.

Ich habe eine Menge Forschung über die Verwendung von Filtern, Q-Objekten, String-Splitting und for-Schleifen, um dies zu erreichen, aber bisher kein Glück.

Der obige Code funktioniert bei der Suche nach "thom", findet aber nichts für "thomas smith". Wie kann ich das umschreiben, um wie beschrieben zu funktionieren?

+0

Gibt es einen bestimmten Grund, warum Sie 'first_name__in' statt' first_name__icontains' verwenden? Denn ich bin mir ziemlich sicher, dass '__in' nicht so funktioniert, wie du es erwarten würdest;) – Wolph

+0

Ich habe es auch mit __icontains ausprobiert. Mein Verständnis von __in ist, dass es auf SQL-Ebene in LIKE übersetzt werden sollte. Während mein SQL rostig ist, hoffe ich, dass es bedeutet, dass es einen Teil der Suchabfrage braucht und es mit dem Feldwert abgleicht, so dass "thomas smith" "thomas" im Vornamen und dann "smith" anpasst Der Nachname. Wenn es so funktioniert, denke ich, dass meine Abfrage funktionieren würde. Offensichtlich nicht. :-) – Antientropic

+1

Der Operator '__contains' wird in' LIKE' konvertiert und '__icontains' wird in' ILIKE' umgewandelt. Das '__in' wird normalerweise für eine Primärschlüssel-Suche verwendet und wird in etwas wie 'id IN (...)' konvertiert. – Wolph

Antwort

1

Ich glaube, dass dies tun, was Sie wollen:

def search(request): 
    name = request.GET.get('s', '').strip().split(' ', 1) 
    client_set = Client.objects.all() 

    if len(name) == 2: 
     first_name, last_name = name 
     client_set = client_set.filter(
      first_name__icontains=first_name, 
      last_name__icontains=last_name, 
     ) 
    else: 
     name = name[0] 
     client_set = client_set.filter(
      client_set.filter(first_name__icontains=name) 
      | client_set.filter(last_name__icontains=name) 
     ) 

    return render_to_response("search.html", { 
     "client_list": client_list, 
     "query": query 
    }, context_instance=RequestContext(request)) 
+1

Sollte client_set in' if else 'nicht client_list sein? –

+0

@anand: ja in der Tat, mein schlechtes. Ich werde es korrigieren – Wolph

+0

Vielen Dank für diesen Code. Es sieht so aus, als würde es genau das tun, was ich brauche. Ich hatte nicht daran gedacht, nur nach einem Zustand zu suchen, wo genau zwei Namen waren, und so zu handeln. Ich werde zurückkommen und mich erneut äußern, wenn ich Zeit habe, an diesem Projekt zu arbeiten und dies umzusetzen. Danke nochmal ! – Antientropic

Verwandte Themen