2015-06-09 73 views
0

我試圖重寫概念queryset在我的子窗體中,以獲取基於從request.POST獲得的區域的自定義列表概念,這裏是我的概念列表,其中我需要根據POST請求進行過濾,這個列表是我的子窗體(InvoiceDetail)的一個fk。有可能有這些過濾器?Django如何覆蓋inlineformset_factory中的子窗體

List of concepts

做一些測試,當我通過最初的數據作爲文件說initial=['concept'=queryset_as_dict]後,它總是返回所有的概念,但是我打印相同的觀點和其確定的過濾器,但也不行當我在模板中呈現時,所以我正在閱讀,我需要使用一些BaseInlineFormset。所以當我測試我得到不同的錯誤:

django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with'] 
'InvoiceDetailFormFormSet' object has no attribute 'fields' 

所以這裏是我的代碼: models.py

class ConceptDetail(CreateUpdateMixin): # here, is custom list if area='default' only returns 10 rows. 
    name = models.CharField(max_length=150) 
    area = models.ForeignKey('procedure.Area') 

class Invoice(ClusterableModel, CreateUpdateMixin): # parentForm 
    invoice = models.SlugField(max_length=15) 

class InvoiceDetail(CreateUpdateMixin): # childForm 
    tax = models.FloatField() 
    concept = models.ForeignKey(ConceptDetail, null=True, blank=True) # fk to override using custom queryset 
    invoice = models.ForeignKey('Invoice', null=True, blank=True) 

views.py

class CreateInvoiceProcedureView(LoginRequiredMixin, PermissionRequiredMixin, CreateView): 
    template_name = 'invoice/invoice_form.html' 
    model = Invoice 
    permission_required = 'invoice.can_check_invoice' 
     def post(self, request, *args, **kwargs): 
    self.object = None 
    form = InvoiceForm(request=request) 
    # initial initial=[{'tax': 16, }] removed 
    invoice_detail_form = InvoiceDetailFormSet(request.POST, instance=Invoice, 
               request=request) 
    return self.render_to_response(
     self.get_context_data(
      form=form, 
      invoice_detail_form=invoice_detail_form 
     ) 
    ) 

forms.py

class BaseFormSetInvoice(BaseInlineFormSet): 
    def __init__(self, *args, **kwargs): 
     # call first to retrieve kwargs values, when the class is instantiated 
     self.request = kwargs.pop("request") 
     super(BaseFormSetInvoice, self).__init__(*args, **kwargs) 
     self.queryset.concept = ConceptDetail.objects.filter(
      Q(area__name=self.request.POST.get('area')) | Q(area__name='default') 
     ) 

class InvoiceForm(forms.ModelForm): 
    class Meta: 
     model = Invoice 
     fields = ('invoice',) 

class InvoiceDetailForm(forms.ModelForm): 
    class Meta: 
     model = InvoiceDetail 
     fields = ('concept',) 

InvoiceDetailFormSet = inlineformset_factory(Invoice, InvoiceDetail, 
              formset=BaseFormSetInvoice, 
              form=InvoiceDetailForm, 
              extra=1) 

我該如何解決它?,我需要閱讀什麼來解決這個問題,我試圖調試過程,我沒有找到答案。 我試着這樣做:

def FooForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(FooForm, self).__init__(*args, **kwargs) 
     self.fields['concept'].queryset = ConceptDetail.objects.filter(area__name='default') 

在inlineformset_factory怎麼能行呢?

回答

0

經過大量測試後,我的解決方案是使用get_context_data覆蓋渲染前的formset。

def get_context_data(self, **kwargs): 
     context = super(CreateInvoiceProcedureView, self).get_context_data(**kwargs) 
     for form in context['invoice_detail_form']: 
      form.fields['concept'].queryset = ConceptDetail.objects.filter(area__name=self.request.POST.get('area')) 
     return context