2016-12-01 2 views
3

私は、次のDjangoのモデルを持っている:リストでモデルをフィルタリングして、別のリストを別のフィールドを設定し

class Profile(models.Model): 
    idNum = models.charField(max_length=10, unique=True) 
    active = models.BooleanField(default=False) 
    idType = models.charField(max_length=10) 

そして、私は2つのリストがあります:idNumsidTypes(同じ長さ):

idNums = ['1', '3', '5', '7', ...] 
idTypes = ['1', '1', '0', '2', '2', ...] 

ProfileidNumsに従ってフィルタリングし、対応するフィールド値をidTypesに設定します。

明白な方法は次のとおりです。

for idNum, idTypes in zip(idNums, idTypes): 
    profile = Profile.objects.get(idNum=idNum) 
    profile.active = True 
    profile.idType = idType 
    profile.save() 

は、このOKですか?つまり、処理するプロファイルインスタンスが何千もある場合は、時間がかかりますか?

もっと速い方法がありますか?私が考えることができるのは、たとえば、インスタンスのリストを最初に取得することです。

profiles = Profile.objects.filter(idNum__in=idNums) 

次に何ですか?

答えて

1

get呼び出しの代わりにfilterを使用することで、SQL selectクエリの数を減らすことはもちろん可能ですが、in_bulkを使用する方が良いと思われます。あなたはIDNUM上のidtypeの原始的な機能依存のいくつかの王を考えることができる、またはあなたは、データベース内の他のソースからそれを盗んことができれば、あなたができれば、しかし

# This will give you a dictionary like {profile_id: Profile, ...} 
profile_dict = Profiles.objects.in_bulk(idNums) 
for idNum, idTypes in zip(idNums, idTypes): 
    profile = profile_dict[idNum] 
    profile.active = True 
    profile.idType = idType 
    profile.save() 

:しかし、あなたはまだ、個々のsave呼び出しを行う必要があります潜在.updateと一緒にF expressionsを利用します。

profiles = Profile.objects.filter(idNum__in=idNums) 
profiles.update(active=True, idType=F('some_column')) 
+0

'idType'は' idNum'とは何の関係もありませんし、それらがユーザーによってアップロードされたファイルから取得されます。その場合、プロセスをスピードアップするにはどのような機会が必要ですか?ありがとう。 –

+0

これが当てはまる場合は、私が提案した最初の解決策(forループを使用)以外のことは考えられません。 –

+0

もう一つの可能​​な解決策:パフォーマンスが本当に重大で、未処理のSQLを恐れていない場合は、次の行に沿って試してみてください。http://stackoverflow.com/a/2528188/4904093もちろん、Pythonコードでクエリを手動で構築する必要があります。 –

関連する問題