2009-07-10 7 views
5

レコードの時間内に内部のWebサイトをコーディングしているうちに、私はいつでもDjangoを読んでいましたが、今はモデルのForeignKeysで非常に非効率的です。djangoの外部フィールドのクエリがたくさんあります

私は基本的にルックアップテーブルである6つのForeignKeysを持つモデルを持っています。すべてのオブジェクトを照会してテンプレートに表示すると、アイテムあたり約10のクエリが実行されます。

class Website(models.Model): 
    domain_name = models.CharField(max_length=100) 
    registrant = models.ForeignKey('Registrant') 
    account = models.ForeignKey('Account') 
    registrar = models.ForeignKey('Registrar') 
    server = models.ForeignKey('Server', related_name='server') 
    host = models.ForeignKey('Host') 
    target_server = models.ForeignKey('Server', related_name='target') 

class Registrant(models.Model): 
    name = models.CharField(max_length=100) 

...と5もっと簡単な表:ここでは、より良いそれを説明するべきいくつかのコードは、です。 155個のウェブサイトのレコードがあり、使用しているビューでは:

Website.objects.all() 

1544クエリの実行が終了します。

<span class="value">Registrant:</span> <a href="/filter/registrant/{{ website.registrant.id }}">{{ website.registrant.name }}</a><br /> 

は、だから私はクエリの多くを実行するために起こっているのを知っている...しかし、これは過剰であるように思える:テンプレートでは、私はのように、外国人のすべてのフィールドを使用しています。これは正常ですか?私はこのようにしてはいけませんか?

私はDjangoには新しく、うまくいけば、何かばかげてやっているだけです。間違いなく素晴らしいフレームワークです。

答えて

5

select_related functionを使用してください。

Website.objects.select_related() 

それは自動的に参加して、クエリが代わりにそれらが使用されるようなオンデマンドでロードする処理を行う際に、それらの外部キーのすべてに従わないようにします。なまけデータベースからDjangoのデータをロードし、デフォルトでは次のような行動

# one database query 
website = Website.objects.get(id=123) 

# first time account is referenced, so another query 
print website.account.username 

# account has already been loaded, so no new query 
print website.account.email_address 

# first time registrar is referenced, so another query 
print website.registrar.name 

などを取得するようにします。選択された関連を使用すると、シーンの背後で結合が実行され、これらの外部キーはすべて自動的に追跡され、最初のクエリにロードされるため、1つのデータベースクエリのみが実行されます。上記の例では、

# one database query with a join and all foreign keys followed 
website = Website.objects.select_related().get(id=123) 

# no additional query is needed because the data is already loaded 
print website.account.username 
print website.account.email_address 
print website.registrar.name 
+0

ありがとうございます。それは間違いなくその機能を持っていることに多くの意味があります。今は9つのクエリを実行しています。テーブルは小さいので、すべてのデータがロードされていることは気にしません(明らかにそれは良い方法です)。 –

関連する問題