Django:如何在Q()语句中使用字符串作为关键字?

Ken*_*ows 8 python django django-queryset

我正在为某个模型编写一个简单的搜索表单.让我们称之为模型Orchard,并给它的属性apples,orangespears,只是为了演示的目的.

因此,表单不需要填写所有字段.所以,你可以搜索applesoranges而不是梨.我需要像这样过滤:

Orchard.objects.filter(apples=request.GET.get('apples'), oranges=request.GET.get('oranges'), pears=request.GET.get('pears'))
Run Code Online (Sandbox Code Playgroud)

但如果pears是空的,则不会返回任何结果.

我的第一个想法是使用Q对象,如下所示:

from django.db.models import Q

options = {}
options['apples'] = request.GET.get('apples')
options['oranges'] = request.GET.get('oranges')
options['pears'] = request.GET.get('pears')

queries = None

for key in options:
    if options[key] != u'':
        if queries:
            queries &= Q(key=options[key]) # <=== problem here
        else:
            queries = Q(key=options[key])  # <=== same problem here

results = Orchard.objects.filter(queries)
Run Code Online (Sandbox Code Playgroud)

问题出现在那些标记的行中.我显然不能只使用"key"作为属性关键字,因为它不需要字符串,它基本上需要一个变量.

那么......我该如何解决这个问题呢?

除非有一个已知的解决方案,不涉及此问题Q.这也会有所帮助.

sec*_*ond 12

这是使用变量作为关键字arg中的键的一般问题.解决方案是将事物包装在dict中并解压缩:

queries &= Q(**{key: options[key]})
Run Code Online (Sandbox Code Playgroud)

或者在你的情况下

for option in options:
    if options[option] is None:
        del(options[option])
# or otherwise only add the ones you actually want to filter on
# then
results = Orchard.objects.filter(**options)
Run Code Online (Sandbox Code Playgroud)