2016-09-24 3 views
0

私のdjangoプロジェクトには、この例では簡略化された3つのモデルがあります:Contact、WorkRelationおよびGroupオブジェクト。Djangoでのクエリの最適化、逆リンクされたオブジェクトのprefact_related

問い合わせ

class Contact(BaseModel): 
    title = models.CharField(max_length=30, blank=True) 
    initials = models.CharField(max_length=10, blank=True) 
    first_name = models.CharField(max_length=30, blank=True) 
    prefix = models.CharField(max_length=20, blank=True) 
    surname = models.CharField(max_length=30) 

    def get_workrelations(self): 
     workrelations = apps.get_model('groups', 'WorkRelation') 
     return workrelations.objects.filter(contact=self) 

    def get_organisations(self): 
     output = "" 
     strings = [] 
     wr = self.get_workrelations() 
     for relation in wr: 
      group = relation.group 
      name = group.name 
      strings.append(s) 
     if len(strings) > 0: 
      output = ", ".join(strings) 
     return output 

WorkRelation

class WorkRelation(BaseModel): 
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE) 
    group = models.ForeignKey(Group, on_delete=models.CASCADE) 
    function = models.CharField(max_length=40, blank=True) 
    email_address = models.EmailField() 
    phone_number = models.CharField(max_length=13, blank=True) 
    description = models.TextField(max_length=400, blank=True) 

グループ

class Group(BaseModel): 
    group_type = models.ForeignKey(GroupType, on_delete=models.CASCADE) 
    name = models.CharField(max_length=60, unique=True) 
    street_name = models.CharField(max_length=40, blank=True) 
    house_number = models.CharField(max_length=10, blank=True) 

この設定に問題I大規模な連絡先セットでget_organisations()を呼び出すときに非常に遅くなります。たとえば、すべての連絡先(私のデモセットの600)をリストし、get_organisations()を呼び出す場合、約1250のクエリが必要です。

私はあなたがprefetch_data()を使ってこれを防ぐことができますが、どういうわけか私のセットアップでこれを動作させることができないことがわかりました。私のクエリを置き換えようとしました

queryset = Contact.objects.prefetch_related('workrelation_set') 

しかし、これは私の前提に反してスピードアップしませんでした。あなたもこれをスピードアップすることが可能かどうか知っていますか?

答えて

1
これにあなたのget_organisationsコードを変更し

def get_organisations(self): 
    return ', '.join(
     workrelation.group.name for workrelation 
     in self.workrelation_set.all() 
    ) 

そして、連絡先オブジェクトを取得するために、このクエリを使用します。

Contact.objects.prefetch_related('workrelation_set__group') 

これは、単一のクエリで結果を返します。

+0

うわー、あなたがどれくらいの間これを探していたのか分かりません。ありがとう! – hY8vVpf3tyR57Xib

関連する問題