2016-12-15 9 views
0

私はDjangoの管理者インラインがドロップダウンを埋めるために不必要なクエリをたくさん行っているというかなり一般的な問題にぶち当たっています。 4つのモデルがあります。ユーザーを見ると、そのユーザーに関連付けられているUserClientRolesが表示され、ClientRoleの名前とクライアントが表示されます。私はちょうど役割の名前を使用するとき、それは各UserClientRoleのために一度問い合わせます(3つの割り当てがあれば、それは3回問い合わせます)。クライアント名を含めると、すべてのクライアント名がすべてのUserClientRoleに対して1回ずつ照会されます。Django adminインラインプリフェッチ対外関係の外国関係

私はここで説明した解決策(Django admin inline: select_related)を試しましたが、サイコロはありませんでした。これは動作を変更しません。また、UserAdminクラスのget_querysetメソッドを無効にしてみました。私が試したことは何もクエリの数を減らします。私は簡潔さのためにいくつかのモデルの詳細を削除しました。

は、ここでのモデルです:

class User(models.Model): 
    id = models.AutoField(primary_key=True) 
    email = models.CharField(unique=True, max_length=200) 


class Client(models.Model): 
    id = models.AutoField(primary_key=True) 
    client_name = models.CharField(unique=True, max_length=200) 
    client_identifier = models.CharField(unique=True, max_length=200) 


class ClientRole(models.Model): 
    client_role_id = models.AutoField(primary_key=True) 
    role_name = models.CharField(unique=True, max_length=200) 
    client = models.ForeignKey(Client) 

    def __unicode__(self): 
     return self.role_name + self.client_id.client_name 


class UserClientRole(models.Model): 
    user_client_role_id = models.AutoField(primary_key=True) 
    client_role = models.ForeignKey(ClientRole) 
    user = models.ForeignKey(User) 

そしてここでは、管理モデルは以下のとおりです。

class UserClientRoleFormset(forms.BaseInlineFormSet): 
    def __init__(self, *args, **kwargs): 
     super(UserClientRoleFormset, self).__init__(*args, **kwargs) 
     self.queryset = self.queryset.prefetch_related("client_role__client") 


class UserClientRoleInline(admin.TabularInline): 
    model = UserClientRole 
    extra = 1 
    formset = UserClientRoleFormset 


@admin.register(User) 
class UserAdmin(admin.ModelAdmin): 
    inlines = (UserClientRoleInline,) 

私が欠けているものを任意の手掛かり?

+0

あなたは私の答えを試しましたか? – e4c5

+0

@ e4c5私はテーブル構造を設計しておらず、書き直す立場にありません。私はあなたが持っている構造と持っている構造の間にある程度の情報の損失があるように感じるので、それは前進であることが私には分かりませんでした – canisrufus

+0

これから遠くには情報損失は全くありません。あなたの既存の構造は、組み込みのdjangoを利用していません。多対多の関係 – e4c5

答えて

1

試してください:あなたはDjangoのORMを使うので、それを認識するのに十分スマートであると思うかもしれないにもかかわらず

self.queryset.select_related('client_role', 'client_role__client') 

Djangoは、クエリの一部として選択するために、どのオブジェクトについての意思決定を行う時に、常に最善ではありません関係の船を横切っている形式のrelated_parent__related_child、そうではありません。したがって、select_relatedまたはprefetch_relatedの両方を指定することは過去に私のために働いていました。私はそれを試してみることをお勧めします!