2012-10-01 19 views
8

私の質問が愚かであることが判明した場合はお詫びしますが、私はDjangoを新しくしています。Djangoモデル - オブジェクトの代わりにidを割り当てよう

BlackListEntry.objects.create(user_banned=int(user_id),user_banning=int(banning_id)) 

私は次のエラーを取得:の

Cannot assign "1": "BlackListEntry.user_banned" must be a "User" instance. 

私はこのようなオブジェクトを作成しようとすると、今

class BlackListEntry(models.Model): 
    user_banned = models.ForeignKey(auth.models.User,related_name="user_banned") 
    user_banning = models.ForeignKey(auth.models.User,related_name="user_banning") 

私は、次のモデルを持っていますもちろん、私は次のようなものに置き換えます:

user_banned = User.objects.get(pk=user_id) 
user_banning = User.objects.get(pk=banning_id) 
BlackListEntry.objects.create(user_banned=user_banned,user_banning=user_banning) 

すべて正常です。問題は次のとおりです。

私のソリューションは両方のユーザーを取得するためにデータベースにヒットしましたか?はいの場合は、回避することは可能ですか?

答えて

10

あなたの質問に対する答えは:はい。

Djangoは少なくとも2回データベースにヒットします.2つは、2つのユーザーオブジェクトを取得し、3つ目は、必要な情報をコミットします。これにより、絶対に不要なオーバーヘッドが発生します。

ちょうど試してみてください。

BlackListEntry.objects.create(user_banned_id=int(user_id),user_banning_id=int(banning_id)) 

これらは、DjangoのORMによって生成されたFKのフィールドのデフォルト名パターンです。これにより、情報を直接設定してクエリを回避することができます。

すでに保存されてBlackListEntryオブジェクトを照会したい場合は、このように、二重のアンダースコアで属性をナビゲートすることができます。

BlackListEntry.objects.filter(user_banned__id=int(user_id),user_banning__id=int(banning_id)) 

これは、あなたがDjangoのクエリセットのプロパティにアクセスする方法です。二重のアンダースコアで。次に、属性の値と比較することができます。

非常に似ていますが、それらは全く異なる働きをします。最初のものは直接属性を設定し、2つ目はdjangoで解析し、それを '__'で分割し、データベースに正しい方法で照会し、2番目の部分は属性の名前です。

IDの代わりにuser_banneduser_banningを実際のユーザーオブジェクトといつでも比較できます。しかし、あなたがまだあなたと一緒にそれらのオブジェクトを持っていない場合、これのための使用はありません。

希望します。

+0

これは私に与えます: 'user_banning__id'はこの関数の無効なキーワード引数です –

+0

申し訳ありませんが、私はあなたがオブジェクトを作成していることを認識しました。したがって、単一のアンダースコアでアクセスする必要があります。私はなぜexplaiに私の答えを編集します。 – Francisco

+0

ありがとう、今それは動作します。私はあなたに+1を追加しますが、私はまだそれを行うにはn00blyです。 –

0

私はあなたがここで説明する方法を使用してアップデートを行うには、生のSQLを記述しなければならない、それを避けるために...あなたがユーザーをフェッチするとき、デシベルを打つために起こっていることを

を信じています:

https://docs.djangoproject.com/en/dev/topics/db/sql/

あなたはそのルートを行くことに決める場合は、SQLインジェクション攻撃から身を守るために責任があるに注意してください。

もう1つの方法は、user_bannedおよびuser_banningオブジェクトをキャッシュすることです。

しかし、おそらく、単にユーザーをつかんでBlackListEntryを作成しても、パフォーマンスに大きな問題はありません。 raw SQLのキャッシュまたは実行は、わずかな利点しか提供しません。これが問題になる前に、おそらく他の問題に遭遇するでしょう。