曲線を滑らかにする

Djangoのほぼすべての機能について、変更および拡張する方法があります。 ツールの動作を変更するためだけにDjango機能の大部分を書き換える必要があることは非常にまれです。 たとえば、フォームの外観を変更する場合、デフォルトの外観を放棄して独自のフィールドを作成するか、独自のHTMLを使用することもできます。 どちらの場合でも、フォームライブラリのその他すべての利点を保持しながら、可能性の範囲で勝ちます。



この拡張は曲線として表すことができます。 一端には基本的なオプションがあり、簡単に記述できますが、制御オプションは制限されます。 曲線の反対側には、静的なHTMLコードを持つフォーム用に特別に作成されたクラスがあります。これは、より高いレベルの制御を提供しますが、作成もより困難です。 フォームの作成の例では、この曲線は非常に滑らかになります。フォームのライブラリの機能の全範囲で、基本オプションを独自のカスタム拡張機能で徐々に置き換える機会があるためです。



ORMのDjango 1.2バージョンがリリースされる前は、このような曲線は似たような外観でしたが、1つの例外がありました。最後に大きなジャンプがありました。 このジャンプは、非標準のSQLクエリを作成する必要がある場合、ORMの制限を超える必要があるという事実のために現れました。 特定のORM機能を使用するには、ユーザーが自分でそれを再作成する必要がありますが、これ自体は災害ではありません。 Django 1.2では、Model.objects.raw()メソッドが追加され、この問題が解決され、ORMのこの曲線が滑らかになりました。



古い方法

Django 1.2のリリース前に、必要に応じてSQLクエリを作成するには、次のように記述する必要がありました。



  django.dbインポート接続から
 library.models import Authorから 

カーソル= connection.cursor()
 query = "SELECT * FROM library_author"
 cursor.execute(クエリ)
結果= cursor.fetchall() 

作成者= []
結果の結果:
     author = Author(*結果)
     authors.append(著者) 




絶対にひどいものではなかったわけではありませんが、ここではSQLクエリの作成に関係のないすべてのORM機能へのアクセスを失います。 特に、クエリ結果のモデルインスタンスへの自動変換は使用できません。 もちろん、失われた機能を復元する中程度の労力を要する方法は存在しますが、実際には自転車の発明になります。



新しい方法

Django 1.2では、直接SQLクエリを作成するには、次のように記述する必要があります。



  library.models import Authorから 

 query = "SELECT * FROM library_author"
 authors = Author.objects.raw(クエリ) 




ここでの著者はRawQuerySetのインスタンスになります。 RawQuerySetはQuerySetによく似ています。 特に、類似点は、反復ごとにクエリ結果からモデルのインスタンスを返す反復可能なオブジェクトであることです。 QuerySetとは異なり、チェーンに埋め込むことができません。 ただし、リクエストは自動的に生成されないため、ここでは重要ではありません。



カーソルデータベースと同様に、クエリパラメータのセットを渡すことができ、Djangoはそれらを慎重にスクリーニングします。



  query = "SELECT * FROM library_author WHERE first_name =%s"
 params =( 'bob'、)
 authors = Author.objects.raw(クエリ、パラメーター) 




素晴らしい! SQLコードは攻撃から保護されています。必要なモデルのインスタンスがあり、自転車の発明はありません。



「それだけではありません!」

ほとんどのDjangoツールと同様に、raw()メソッドには、不快な状況での追加機能や特に複雑なクエリのための余地があります。



独立したフィールド順序

Model.objects.raw()メソッドの場合、要求時にフィールドが返される順序は関係ありません。 重要なのは、要求フィールドの名前がモデルのフィールドに対応するかどうかだけです。



  #これらのクエリはすべて同じように機能します
 Author.objects.raw( "SELECT * FROM library_author")
 Author.objects.raw( "SELECT id、first_name、last_name FROM library_author")
 Author.objects.raw( "SELECT last_name、id、first_name FROM library_author") 




注釈

クエリへの応答で、モデルクラスに存在しないフィールドを取得した場合、RawQuerysetメソッドによって返されるモデルインスタンスへの注釈として追加されます。 これにより、アクションまたは計算のすべての利点を簡単に使用でき、その実装はデータベースレベルでより効率的です。



  >>> authors = Author.objects.raw( "SELECT *、age(birth_date)as age FROM library_authors")
 >>>著者の著者:
 ...「%s is%s」を印刷します。  %(author.first_name、author.age)
ジョンは37歳です。
ジェーンは42歳です。
 ... 




モデルとクエリフィールド間の関係の定義

何らかの理由でクエリフィールドの名前とモデルフィールドの名前を正確に一致させることができない場合、Model.objects.raw()メソッドはそれを手動で指定する機能を提供します。



クエリフィールドをモデルフィールドにマップするには、必要な一致を含む辞書をraw()メソッドのパラメーターの1つとして使用するだけです。 対応は、モデルのフィールドと比較できなかったフィールドについてのみ決定する必要があります。



  field_map = {'first': 'first_name'、 'last': 'last_name'}
     query = 'SELECT id、first_name AS first、last_name as last FROM library_author'
     authors = Author.objects.raw(クエリ、翻訳= field_map) 




保留中のフィールド

モデルで想定されているが、要求によって返されないフィールドは、 保留中としてマークさます。 これらは、モデルインスタンスフィールドを照会する場合にのみ入力されます。 これは、モデルの「実際の」テーブルからデータが要求されない場合、またはテーブル自体が十分に大きい場合に役立ちます。 ここでは、主キーを遅延させることはできず、すべてのリクエストで返す必要があることに留意する必要があります。 クエリが主キーを返さない場合、InvalidQuery例外がスローされます。



制限事項

raw()メソッドのアクションにはいくつかの制限があります。 最も重要なのは、raw()メソッドがSELECTクエリのみをサポートすることです。 他の種類のクエリを使用しようとすると、InvalidQuery例外がスローされます。 当初、これは保護の目的で行われましたが、一部は、SELECTタイプのクエリ以外のモデルのインスタンスを返す意味がないため、この方法で行われました。 ダイレクトSQLを使用してデータを変更することは、Djangoで行う価値のある最後のことです。 これらのアクションを引き起こさないために、ユーザーにとってより便利なものにしたいわけではありません。 SELECTクエリに加えて直接SQLクエリを使用する必要がある場合は、常にデータベースカーソルを作成してそこから作業する機会があります。



それだけです

まあ、それだけです。 バージョンDjango 1.2では、必要に応じてSQLクエリを操作することが大幅に簡素化されています。 上記で説明した曲線は、はるかに滑らかな外観です。 この機能の公式ドキュメントは、SQLセクションあります



All Articles