4 Stimmen

Django: Generierung eines Querysets aus einer GET-Anfrage

Ich habe ein Django-Formular Setup mit GET-Methode. Jeder Wert entspricht den Attributen eines Django-Modells. Was wäre der eleganteste Weg, um die Abfrage zu generieren? Derzeit ist dies, was ich in der Ansicht tun:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        query_attributes['color'] = request.GET.get('color', '')
        if not query_attributes['color']: del query_attributes['color']

        query_attributes['shape'] = request.GET.get('shape', '')
        if not query_attributes['shape']: del query_attributes['shape']

        items = Items.objects.filter(**query_attributes)

Aber ich bin mir ziemlich sicher, dass es einen besseren Weg gibt, das zu tun.

6voto

Sam Dolan Punkte 30838

Sie könnten es mit einer Liste comp und und "interested params" Satz zu tun:

def search_items(request):
    if 'search_name' in request.GET:
        interested_params = ('color', 'shape')
        query_attrs = dict([(param, val) for param, val in request.GET.iteritems() 
                            if param in interested_params and val])

        items = Items.objects.filter(**query_attrs)

Nur so zum Spaß (aka mach das nicht wirklich) könntest du es in einer Zeile machen:

def search_items(request):
    items = Items.objects.filter(
        **dict([(param, val) for param, val in request.GET.iteritems() 
                if param in ('color', 'shape') and val])
    ) if 'search_name' in request.GET else None

1voto

Die grundsätzliche Herangehensweise an das Problem scheint vernünftig zu sein, aber die Art und Weise, wie Sie es formuliert haben, sieht ein wenig komisch aus. Ich würde es wahrscheinlich so machen:

def search_items(request):
    if 'search_name' in request.GET:
        query_attributes = {}

        color = request.GET.get('color', '')
        if color:
            query_attributes['color'] = color

        shape = request.GET.get('shape', '')
        if shape:
            query_attributes['shape'] = shape

        items = Items.objects.filter(**query_attributes)

0voto

Dmitry Shevchenko Punkte 30176

Wenn Sie möchten, dass es vollständig dynamisch ist, können Sie ein wenig Modell-Introspektion verwenden, um herauszufinden, welche Felder Sie tatsächlich abfragen können, und nur nach diesen filtern.

Allerdings erlaubt diese Lösung nicht die Verwendung von __lookups in GET-Parametern, ich weiß nicht, ob Sie das brauchen.

def search_items(request):
    if 'search_name' in request.GET:
        all_fields = Items._meta.get_all_field_names()
        filters = [(k, v) for k, v in request.GET.items() if k in all_fields]

        items = Items.objects.filter(*filters)

0voto

nide Punkte 34
def search_items(request):
    try:
        items = Items.objects.filter(**dict([
            (F, request.GET[F]) for F in ('color', 'shape')
        ]))

    except KeyError:
        raise Http404

Angenommen, "Farbe" und "Form" sind erforderliche GET-Parameter. Ein vordefiniertes Tupel von Filterparametern wird aus Sicherheitsgründen bevorzugt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X