如何在内联formset上使用新的form_kwargs?

时间:2016-07-25 05:33:09

标签: django django-forms

在1.9中,form_kwargs有一个新的formset_factory feature,允许您为formset中的特定字段设置查询集。我的问题是,如何为inlineformset_factory实现同样的目标?

执行以下操作无效:

/* Pseudo code of my actual models */
class Account(models.Model):
    fields here...

class Invoice(models.Model):
    fields here...

class InvoiceLineItem(models.Model):
    account = ForeignKey(Account)
    invoice = ForeignKey(Invoice)
    description = CharField
    amt = DecimalField

/* === End of Pseudo Code === */


# Real code that fails:

InvoiceLineItemFormset = inlineformset_factory(Invoice, InvoiceLineItem, fields=('description', 'account', 'amt'))
accts = Account.objects.filter(fund__pk = self.kwargs['fpk'])
invoice_line_item_form = InvoiceLineItemFormset(form_kwargs={'account':accts})

我得到的错误是:

__init__() got an unexpected keyword argument 'account'

错误是突出显示模板中的以下两行:

{{ invoice_line_item_form.management_form }}
{% for ili in invoice_line_item_form %}

我不确定我是否实现了这个错误(因为它是专为formset_factory设计的,我在inlineformset_factory上使用它)或者我设置错了。有什么想法吗?

2 个答案:

答案 0 :(得分:4)

class InvoiceLineItemForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.account = kwargs.pop('account')
        super(InvoiceLineItemForm, self).__init__(*args, **kwargs)
        self.fields['account'].queryset = self.account

InvoiceLineItemFormSet = inlineformset_factory(
    Invoice, InvoiceLineItem, form=InvoiceLineItemForm,
    fields=('description', 'account', 'amt'))

formset = InvoiceLineItemFormSet(form_kwargs={'account': account})

答案 1 :(得分:0)

我尝试在上下文中使用接受的答案

models.py

{% extends "layout.html" %}

{% block head %}
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script src="{{ url_for('static', filename='index.js') }}"></script>
{% endblock %}

{% block title %}
messages
{% endblock %}

{% block body %}
<div id="channels">
</div>
<hr>
<form id="channel">
    <input type="text" placeholder="Channel Name" id="ch">
    <input type="submit">
</form>
{% endblock %}

views.py:

class DetailMatiere(models.Model):
    code  = models.CharField(max_length=10, unique=True)
    libelle = models.CharField(max_length=100)
    cat = models.ForeignKey('catdetailmatiere', on_delete=models.PROTECT)
    matiere = models.ForeignKey('matiere', on_delete=models.PROTECT)
    def __str__(self):
        return self.code

class DetailService(models.Model):
    annee = models.ForeignKey(base_models.Annee, on_delete=models.PROTECT)
    detail_matiere = models.ForeignKey('detailmatiere', on_delete=models.PROTECT)
    enseignant = models.ForeignKey(base_models.EnseignantActif, on_delete=models.PROTECT)
    nb_heure_eff = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    class Meta:
        unique_together = ('annee', 'detail_matiere', 'enseignant')
    def __unicode__(self):
        return self.detail_matiere

forms.py:

class DetailMatiereUpdate(UpdateView):
    form_class = DetailMatiereForm
    def get_form_kwargs(self):
        kwargs = super(DetailMatiereUpdate, self).get_form_kwargs()
        kwargs['annee'] = self.request.session['annee']
        return kwargs

但是我得到了:

class DetailMatiereDetailServiceForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.annee = kwargs.pop('annee')
        super(DetailMatiereDetailServiceForm, self).__init__(*args, **kwargs)
        self.fields['nb_heure_eff'].widget.attrs['style'] = 'width:6ch'
        self.fields['annee'].queryset = self.annee

DetailMatiereDetailServiceFormSet = forms.inlineformset_factory(DetailMatiere, DetailService,
       form=DetailMatiereDetailServiceForm, extra=1, fields=('annee', 'detail_matiere', 'enseignant', 'nb_heure_eff'))
formset = DetailMatiereDetailServiceFormSet(form_kwargs={'annee': annee})