2013-03-04 61 views
6

我正在爲我的Django應用程序構建一個csv導入表單,並希望爲了驗證目的而在ModelFormSet中顯示要導入的行。阻止Django爲ModelFormSet中的每個表單查詢ForeignKey選項

因此我添加了相關ModelAdmin的視圖,該視圖從csv讀取行並打印ModelFormSet(queryset=an_empty_queryset, initial={data_from_the_csv})

的問題是,該模型在表單集數據庫查詢,以便填充ModelChoiceField的選項發出各種形式通過ForeignKey領域和每個字段引用其他三款車型。

爲什麼Django不緩存表單(因爲它已被多次使用)或者是否已有方法可以完成這個我不知道的事情呢?

+1

django1.5有模型內存緩存。 – danihp 2013-03-04 14:27:33

+1

你說得對(https://docs.djangoproject.com/en/1.5/releases/1.5/#caching-of-related-model-instances),但不幸的是它不會影響這個問題。 – jnns 2013-03-04 23:22:49

+0

我已經做了一些小技巧來解決這個問題:http://stackoverflow.com/a/43105646/8450 – 2017-03-29 23:07:15

回答

11

Django formsets只是將表單創建的所有細節委託給表單對象本身,並且各個表單實例並不知道其他表單對象,因此每個用戶都必須查詢自己的選擇並不意外。

緩存也可能會導致意外的副作用 - 例如,窗體的__init__功能可能是依賴於它接收到的initial數據,使緩存form對象不正確。

減少查詢次數的最佳方法是檢索選擇查詢集一次,然後將它們傳遞給您的構造函數中的表單類。這將需要定義一個自定義ModelForm和一個自定義ModelFormSet

你的形式將需要直接接受的選擇一個構造函數:

from django.forms.models import ModelForm 

class MyForm(ModelForm): 
    def __init__(self, my_field_choices=None, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['my_field'].choices = my_field_choices 

而且你的表單集將需要重寫運行的查詢集,並將它們傳遞到形式的方法,因爲他們正在構建:

from django.forms.models import BaseModelFormSet 

class MyFormSet(BaseModelFormSet): 
    def _construct_forms(self): 
     # instantiate all the forms and put them in self.forms 
     self.forms = [] 

     # Define each of your choices querysets 
     my_field_choices = Model.object.filter(...) 

     #Add your querysets to a dict to pass to the form 
     form_defaults = {'my_field_choices': my_field_choices, } 

     for i in xrange(min(self.total_form_count(), self.absolute_max)): 
      self.forms.append(self._construct_form(i, **form_defaults)) 

(見the Django source尋找到如何做到這一點的工作)

+0

感謝您花時間回答我的問題。您的解決方案就是我的想法,但現在我知道這是一條路! – jnns 2013-03-07 14:23:30

+0

我使用這個解決方案的同樣的問題,但當保存我得到「不能分配」u'7'「:」Stop.city「必須是」城市「的實例。」 Stop是具有City fk的ModelForm(用於構建formset)。有沒有什麼辦法可以傳遞它呢?似乎需要花費太多的時間來進一步這樣做。 – mariodev 2013-07-20 13:52:50

+0

@mariodev,我想你可能需要發佈一些更多的代碼來幫助解釋/追蹤這個問題。這個正義可能沒有足夠的評論空間,所以它可能更適合自己的問題。 – 2013-07-23 16:39:55

相關問題