Bei einer Klasse:
from django.db import models
class Person(models.Model):
name = models.CharField(max_length=20)
Ist es möglich und wenn ja wie, ein QuerySet zu haben, das basierend auf dynamischen Argumenten filtert? Beispielsweise:
# Instead of:
Person.objects.filter(name__startswith='B')
# ... and:
Person.objects.filter(name__endswith='B')
# ... is there some way, given:
filter_by = '{0}__{1}'.format('name', 'startswith')
filter_value = 'B'
# ... that you can run the equivalent of this?
Person.objects.filter(filter_by=filter_value)
# ... which will throw an exception, since `filter_by` is not
# an attribute of `Person`.
python
django
django-models
Brian M. Hunt
quelle
quelle
Ein vereinfachtes Beispiel:
In einer Django-Umfrage-App wollte ich eine HTML-Auswahlliste mit registrierten Benutzern. Da wir jedoch 5000 registrierte Benutzer haben, brauchte ich eine Möglichkeit, diese Liste anhand von Abfragekriterien zu filtern (z. B. nur Personen, die einen bestimmten Workshop abgeschlossen haben). Damit das Umfrageelement wiederverwendbar ist, musste die Person, die die Umfragefrage erstellt, diese Kriterien an diese Frage anhängen können (ich möchte die Abfrage nicht fest in der App codieren).
Die Lösung, die ich gefunden habe, ist nicht 100% benutzerfreundlich (erfordert die Hilfe einer technischen Person, um die Abfrage zu erstellen), löst jedoch das Problem. Beim Erstellen der Frage kann der Editor ein Wörterbuch in ein benutzerdefiniertes Feld eingeben, z.
Diese Zeichenfolge wird in der Datenbank gespeichert. Im Ansichtscode wird es als zurückgegeben
self.question.custom_query
. Der Wert davon ist eine Zeichenfolge, die wie ein Wörterbuch aussieht . Wir verwandeln es mit eval () wieder in ein echtes Wörterbuch und füllen es dann mit ** kwargs in das Abfrageset:quelle
eval()
des Benutzerimports ist eine schlechte Idee, selbst wenn Sie Ihren Benutzern vollkommen vertrauen. Ein JSON-Feld wäre hier eine bessere Idee.Django.db.models.Q ist genau das, was Sie auf Django-Weise wollen.
quelle
Q(**filters)
Wenn Sie Q-Objekte dynamisch aufbauen möchten, können Sie sie in eine Liste.filter(*q_objects)
einfügen und verwenden oder die bitweisen Operatoren verwenden, um die Q-Objekte zu kombinieren.Ein wirklich komplexes Suchformular zeigt normalerweise an, dass ein einfacheres Modell versucht, seinen Ausweg zu finden.
Wie genau erwarten Sie die Werte für den Spaltennamen und die Operation? Wo sehen Sie die Werte erhalten
'name'
ein'startswith'
?Ein "Such" -Formular? Du wirst - was? - Wählen Sie den Namen aus einer Liste von Namen? Wählen Sie die Operation aus einer Liste von Operationen aus? Während offen, finden die meisten Menschen dies verwirrend und schwer zu bedienen.
Wie viele Spalten haben solche Filter? 6? 12? 18?
Spezifische Filtertasten. Warten Sie ... So funktioniert der Django-Administrator. Bestimmte Filter werden zu Schaltflächen. Und es gilt die gleiche Analyse wie oben. Einige Filter sind sinnvoll. Eine große Anzahl von Filtern bedeutet normalerweise eine Art erste normale Formverletzung.
Viele ähnliche Felder bedeuten oft, dass mehr Zeilen und weniger Felder vorhanden sein sollten.
quelle