2

重複の可能性:
ユーザーからの動的な Q オブジェクトを使用してフィルター処理しますか?

アプリのフィルター機能に取り組んでいます。コンマ区切りの文字列を jquery 経由で Django に送信します (jquery 内でスペースを + に置き換えて、ネットワーク経由で送信できるようにします)。

/?ajax&sales_item=t2,+t1

ビューで GET パラメータを取得すると、Django がすでに + をスペースに置き換えていることがわかります。これはすばらしいことです。次に、キーワードをコンマで分割し、空白を取り除きます。

sales_item_raw = request.GET['sales_item']
sales_item_keywords = sales_item_raw.split(',')            

最初に、指定された名前が販売アイテムとして存在するかどうかを確認する必要があります。を使用する必要があるicontainsため、sales_items複数のアイテムを使用できます。

for item in sales_item_keywords:
        sales_items = profile.company.salesitem_set.filter(item_description__icontains=item.strip())            

最後になりましたが、クエリセットは、指定された sales_items の取引をフィルタリングするために使用されます。

deals_queryset = deals_queryset.filter(sales_item__in=sales_items)

ユーザーが 1 つのキーワードのみをフィルタリングする場合は正常に機能しますが、キーワードが 2 つある場合は、sales_itemsループの反復ごとに明らかに上書きされます。

これを解決する最もパフォーマンスの高い方法は何ですか? sales_items各繰り返しの内容をループ外のリストに追加しますか? そして最終的に新しいリストを最終的に送信しdeals_queryset.filterますか?

これがこれを解決する良い方法かどうかはわかりません...

4

1 に答える 1

0

Django のQオブジェクトを使用して、フィルターに「or」ロジックを作成します。

# create a chain of Qs, one for each item, and "or" them together 
q_filters = Q(item_description__icontains=sales_item_keywords[0].strip())
for item in sales_item_keywords[1:]:
    q_filters = q_filters | Q(item_description__icontains=item.strip())   

# do a single filter with the chained Qs
profile.company.salesitem_set.filter(q_filters)

最初のQをエレガントに処理する方法がわからないため、これは醜いコードです。最初のものを含む他のすべてのQをチェーンできる「空の」Qとは何かがわからないためです。(使用できると思いますがQ(pk=pk)、それは別の意味で醜いです。)

編集:上記のイグナシオのリンクは道を示しています、つまり

q_filters = reduce(operator.or_, (Q(item_description__icontains=item.strip()) for item in sales_items_keywords))
profile.company.salesitem_set.filter(q_filters)
于 2012-08-31T13:23:03.033 に答える