Django-Filter-Abfrage-Set für "Tupel" von Werten für mehrere Spalten

8

Sagen Sie, ich habe ein Modell:

%Vor%

und sagen, ich habe eine Liste von zwei Vornamen: first_list = ['Bob', 'Rob'] Und ich habe eine Liste mit zwei Nachnamen: last_list = ['Williams', 'Williamson'] . Wenn ich dann alle auswählen wollte, deren Vorname in first_list war, könnte ich folgendes ausführen:

%Vor%

und wenn ich jeden auswählen wollte, dessen Nachname in last_list war, könnte ich tun:

%Vor%

So weit, so gut. Wenn ich beide Einschränkungen gleichzeitig ausführen möchte, ist das einfach ...

%Vor%

Wenn ich die or -Stilsuche anstelle der and -Stilsuche machen möchte, kann ich das mit Q objects tun:

%Vor%

Aber was ich im Sinn habe, ist etwas subtiler. Was ist, wenn ich nur ein Abfrage-Set zurückgeben möchte, das bestimmte Kombinationen von Vor- und Nachnamen zurückgibt? I.e. Ich möchte die Person -Objekte zurückgeben, für die (Person.firstname, Person.lastname) in zip(first_names, last_names) steht. I.e. Ich möchte jeden mit dem Namen Bob Williams oder Rob Williamson zurückbekommen (aber nicht irgendjemanden namens Bob Williamson oder Rob Williams).

In meinem tatsächlichen Anwendungsfall hätten first_list und last_list jeweils ~ 100 Elemente.

Im Moment muss ich dieses Problem in einer Django-App lösen. Aber ich bin auch neugierig auf die beste Möglichkeit, dies in einem allgemeineren SQL-Kontext zu handhaben.

Danke! (Und bitte lassen Sie mich wissen, wenn ich etwas klären kann.)

    
8one6 24.11.2013, 17:46
quelle

2 Antworten

9

Ich sehe nicht viele Lösungen außer einer großen OR-Klausel:

%Vor%     
bruno desthuilliers 24.11.2013, 17:58
quelle
2

Brunos Antwort funktioniert, aber es fühlt sich für mich schmutzig an - sowohl auf der Python-Ebene als auch auf der SQL-Ebene (eine große Verkettung von ORs). In MySQL können Sie mindestens die folgende SQL-Syntax verwenden:

%Vor%

Djangos ORM bietet keine direkte Möglichkeit, dies zu tun, deshalb verwende ich Raw SQL:

%Vor%

(Dies ist eine Liste mit einem Element, das die einzelnen% s in der Abfrage abgleicht. Das Element ist ein iterbares Tupel, daher wird das% s in eine SQL-Liste von Tupeln konvertiert.)

Anmerkungen:

  1. Wie gesagt, das funktioniert für MySQL. Ich bin mir nicht sicher, welche anderen Backends diese Syntax unterstützen.
  2. Ein Fehler in python-mysql, der sich auf dieses Verhalten bezieht, wurde im November 2013 / MySQLdb 1.2.4 behoben, also stellen Sie sicher, dass Ihre Python MySQLdb-Bibliotheken nicht älter sind als diese.
Amichai Schreiber 03.06.2015 09:04
quelle

Tags und Links