it-swarm.com.de

Wie filtert man in Django ein QuerySet mit dynamischen Feldsuchen?

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`.
147
Brian M. Hunt

Die Argumenterweiterung von Python kann verwendet werden, um dieses Problem zu lösen:

kwargs = {
    '{0}__{1}'.format('name', 'startswith'): 'A',
    '{0}__{1}'.format('name', 'endswith'): 'Z'
}

Person.objects.filter(**kwargs)

Dies ist eine sehr verbreitete und nützliche Python Redewendung.

282
Daniel Naab

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 nach Abfragekriterien zu filtern (z. B. nur nach Personen) Damit das Umfrageelement wiederverwendbar ist, musste die Person, die die Umfragefrage erstellt, in der Lage sein, diese Kriterien mit dieser Frage zu verknüpfen (ohne die Abfrage fest zu codieren) die App).

Die Lösung, die ich gefunden habe, ist nicht 100% benutzerfreundlich (für die Erstellung der Abfrage ist die Hilfe eines Technikers erforderlich), löst jedoch das Problem. Beim Erstellen der Frage kann der Editor ein Wörterbuch in ein benutzerdefiniertes Feld eingeben, z.

{'is_staff':True,'last_name__startswith':'A',}

Diese Zeichenfolge wird in der Datenbank gespeichert. Im Ansichtscode wird es als self.question.custom_query Zurückgegeben. Der Wert davon ist ein String, der sieht aus wie ein Wörterbuch. Wir wandeln es mit eval () wieder in ein real - Wörterbuch um und fügen es dann mit ** kwargs in den Query-Satz ein:

kwargs = eval(self.question.custom_query)
user_list = User.objects.filter(**kwargs).order_by("last_name")   
6
shacker

Django.db.models.Q ist genau das, was Sie in einer Django Weise wollen.

5
Brent81