2

私はそのようなモデルを持っています:

class Category(Model):
    ...
    type = models.CharField(max_length=255, choices=settings.CATEGORIES)

class Product(models.Model):
    ...
    categories = models.ManyToManyField(Category)

ユーザーが入力したカテゴリのリストがあります(形式は任意です):

c = [<Category: G, type: producer>, <Category: L, type: producer>, <Category: Teen, type: age>, <Category: Man, type: sex>]

ここで、カテゴリ内のすべての製品に、タイプ「プロデューサー」の「G」または「L」、タイプ「年齢」の「ティーン」、タイプ「性別」の「男性」が必要です。たとえば、次のクエリセットを実行しています。

Product.objects.filter(Q(categories=c[0])|Q(categories=c[1]), Q(categories=c[2]), Q(categories=c[3])

そのようなクエリがある:

SELECT "shop_product"."id", "shop_product"."title", "shop_product"."description",
"shop_product"."price", "shop_product"."code", "shop_product"."stored_count",
"shop_product"."sold_count", "shop_product"."added_date" FROM "shop_product"
INNER JOIN     "shop_product_categories" ON ("shop_product"."id" =   
"shop_product_categories"."product_id")    WHERE 
(("shop_product_categories"."category_id" = 1 OR 
"shop_product_categories"."category_id" = 2) AND    
"shop_product_categories"."category_id" = 4 AND 
"shop_product_categories"."category_id" = 6)

そのような要件に適合するオブジェクトが少なくとも1つありますが、querysetは何も返しません。何か提案はありますか?

4

1 に答える 1

2

カスケード フィルタリングを行う必要があります。そうしないと、現在の選択で"shop_product_categories"."category_id"、値が 1/2 と 4 と 6 のすべての製品が同時に返されます。必要なものを返すクエリセットの例を次に示します。

Product.objects.filter(categories__in=c[0:2])
               .filter(categories=c[2])
               .filter(categories=c[3])
               .distinct()

次のようなSQLを生成します。

SELECT DISTINCT "test1_product"."id" FROM "test1_product" INNER JOIN "test1_product_categories" ON ("test1_product"."id" = "test1_product_categories"."product_id") 
    INNER JOIN "test1_product_categories" T4 
        ON ("test1_product"."id" = T4."product_id")
    INNER JOIN "test1_product_categories" T6 
        ON ("test1_product"."id" = T6."product_id") 
WHERE ("test1_product_categories"."category_id" IN (1, 2) 
    AND T4."category_id" = 3 
    AND T6."category_id" = 4 )
于 2012-07-06T10:50:58.723 に答える