2015-04-15 85 views
5

上的Python 3.4.1將Django 1.8高配車型:Django管理在線:select_related

class Product(models.Model): 
    name = models.CharField(max_length=255) 
    # some more fields here 

    def __str__(self): 
     return self.name 


class PricedProduct(models.Model): 
    product = models.ForeignKey(Product, related_name='prices') 
    # some more fields here 

    def __str__(self): 
     return str(self.product) 

class Coming(models.Model): 
    # some unimportant fields here 


class ComingProducts(models.Model): 
    coming = models.ForeignKey(Coming) 
    priced_product = models.ForeignKey(PricedProduct) 
    # more unimportant fields 

及以下admin.py:

class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline): 
    model = ComingProducts 


class ComingAdmin(admin.ModelAdmin): 
    inlines = [ComingProductsInline] 

當然,我有多次的查詢問題到數據庫:我有一個查詢列表中的每個項目和查詢每一行。所以,有100個項目我得到100^2個查詢。 我已經解決了每個查詢的問題Caching queryset choices for ModelChoiceField or ModelMultipleChoiceField in a Django form 但我仍然有str方法的問題。我已嘗試以下步驟:

1)加入到prefetch_related ComingAdmin:

def get_queryset(self, request): 
    return super(ComingAdmin, self).get_queryset(request). \ 
    prefetch_related('products__product') 

2)添加到select_related ComingProductInline:

def get_queryset(self, request): 
    return super(ComingProductsInline, self).get_queryset(request). \ 
    select_related('priced_product__product') 

3)定義定製形式用於在線和添加select_related到字段查詢集:

class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline): 
    model = ComingProducts 
    form = ComingProductsAdminForm 

class ComingProductsAdminForm(ModelForm): 
    def __init__(self, *args, **kwargs): 
       super(ComingProductsAdminForm, self).__init__(args, kwargs) 
       self.fields['priced_product'].queryset = PricedProduct.objects.all(). \ 
       select_related('product') 

    class Meta: 
     model = ComingProducts 
     fields = '__all__' 

4)定義自定義表單集:

class ComingProductsInline(ForeignKeyCacheMixin, admin.TabularInline): 
    model = ComingProducts 
    formset = MyInlineFormset 

class MyInlineFormset(BaseInlineFormSet): 
    def __init__(self, data=None, files=None, instance=None, 
      save_as_new=False, prefix=None, queryset=None, **kwargs): 
     super(MyInlineFormset, self).__init__(data, files, instance, 
              save_as_new, prefix, queryset, **kwargs) 
     self.queryset = ComingProducts.objects.all(). \ 
     prefetch_related('priced_product__product') 

5)不同的組合爲以前的4種方法

並沒有什麼幫助:爲PricedProduct STR的每一個呼叫使得Django的執行對產品表的查詢。所有這些方法都是在stackoverflow中提到的,但他們處理了ModelAdmin,並沒有幫助Inline。我錯過了什麼?

回答

1

我目前正在處理類似的問題。我發現的內容記錄在此線程中:Translatable Manytomany fields in admin generate many queries

我做的一個重要觀察是我的解決方案僅適用於Django 1.7x而不適用於1.8。與d1.7完全相同的代碼,我有10^1個查詢的順序,並且隨着d1.8的新安裝,我有10^4個。

3

該formset解決方案不會爲我工作,但有一個稍微不同的方式:

class MyInlineFormset(BaseInlineFormSet): 
    def __init__(self, *args, **kwargs): 
     super(MyInlineFormset, self).__init__(*args, **kwargs) 
     self.queryset = self.queryset.prefetch_related('priced_product__product') 

的BaseInlineFormSet類過濾查詢集爲你,你需要採取過濾的queryset,並添加預取。使用你的formset實現(all()queryset),你會得到無關的ComingProduct對象,並且它可能需要太長時間才能呈現。當它是篩選後的查詢集時,它會非常快速地呈現。

+0

哦。這是一種生活救星。我有一個模型A,它有很多模型B的內聯.B有三個m2m和兩個fk關係。此外。模型翻譯被使用。另外,Grappelli的自動完成功能也有所幫助。 – Aitvaras

+0

不幸的是,它在Django 2.0中不起作用 – ramusus

+0

是怎麼回事?它看起來不像Django的相關代碼已經改變 – noamk