4

簡単に言うと、フィルター内にあるすべてのクエリのテーブル名が u0、u1、... に名前変更されるため、追加の where 句はどのテーブルを指すかわかりません。このデータをサブ選択する可能性のあるすべての方法について、すべてのクエリを手動で作成する必要はありません。現在の回避策は、余分なクエリを pk values_lists に変換することですが、それらは本当に遅く、忌まわしいものです。

これがすべての外観です。products_product.id を指す最初の sql 行を除いて、このマネージャー メソッドの余分な内容の詳細はほとんど無視できます。

def by_status(self, *statii):
    return self.extra(where=["""products_product.id IN                                                                                                                                                  
        (SELECT recent.product_id                                                                                                                                                                          
          FROM (                                                                                                                                                                                           
            SELECT product_id, MAX(start_date) AS latest                                                                                                                                                   
            FROM products_productstatus                                                                                                                                                                    
            GROUP BY product_id                                                                                                                                                                            
          ) AS recent                                                                                                                                                                                      
          JOIN products_productstatus AS ps ON ps.product_id = recent.product_id                                                                                                                           
          WHERE ps.start_date = recent.latest                                                                                                                                                              
            AND ps.status IN (%s))""" % (', '.join([str(stat) for stat in statii]),)])

これは、products_product テーブルのみが関係するすべての状況でうまく機能します。

これらの製品をサブセレクトにしたい場合は、次のようにします。

Piece.objects.filter(
    product__in=Product.objects.filter(
        pk__in=list(
            Product.objects.by_status(FEATURED).values_list('id', flat=True))))

クエリ セットの一般化された機能を維持しながら、追加の where 句を使用するにはどうすればよいですか?

4

1 に答える 1

3

最初は、この問題は私には完全に明確ではありません。質問の 2 番目のコード ブロックは、実行したい実際のコードですか? この場合、副選択が実行されないため、クエリは期待どおりに機能するはずです。

list()2 番目のクエリが実行されるのを防ぐために、サブセレクトの周りを使わずに 2 番目のコード ブロックを使用するとします。


djangoのドキュメントでは、extra method に関するドキュメントでこの問題について言及しています。しかし、この問題を克服するのは簡単ではありません。

最も簡単だが最も「ハキーな」解決策は、追加のメソッドでクエリを実行するテーブルに対して、django によって生成されたテーブル エイリアスを観察することです。常に同じ方法でクエリを作成する限り、このエイリアスの永続的な名前付けに依存できます (結合を引き起こす複数のextraメソッドまたは呼び出しの順序を変更しないでください)。filter

以下を使用して、DB クエリセットで実行されるクエリを検査できます。

print Model.objects.filter(...).query

これにより、クエリするテーブルに使用されているエイリアスが明らかになります。

于 2010-07-20T20:22:47.660 に答える