我在views.py中有以下内容来生成一个页面,该页面显示用户“资格”的内联表单集
from django.db.models import User
from models import UserQualification
def edit_quals(request):
QualsFormSet = inlineformset_factory(User, UserQualification, fields=('qualification', 'qualification_year', 'qualification_source'))
if request.method == 'POST':
formset = QualsFormSet(request.POST, request.FILES, instance = request.user)
if formset.is_valid():
formset.save()
#send user somewhere
return HttpResponseRedirect(request.user.get_profile_url())
else:
formset = QualsFormSet(instance = request.user)
return render_to_response("edit_quals.html", {
"formset": formset,
}, context_instance=RequestContext(request))
这很好用,但是,我想创建一个formset
只包含某些'UserQualification'对象(即只有那些标记为某种类型的对象),所以当用户访问此页面时仅编辑其资格的子集。这个参考似乎是我想要的:http://docs.djangoproject.com/en/1.1/topics/forms/modelforms/#changing-the-queryset。它处理的是modelformset_factory,但是inlineformset_factory是基于先前的,所以我认为同样的事情应该有效:
formset = QualsFormSet(instance = request.user, queryset=UserQualification.objects.filter(type__startswith='xyz'))
但是转到此页面只会产生一个TypeError: init ()得到一个意外的关键字参数'queryset'。该引用列出了两种方法,我遇到了两种方法。
答案 0 :(得分:2)
我在这里提供了一个稍微简单的问题答案: Limit Django's inlineformset_factory to only create new objects
对于你想要做的事情,InlineFormSet类看起来像这样:
class BaseInlineFilteredFormSet(BaseInlineFormSet):
def get_queryset(self):
## See get_queryset method of django.forms.models.BaseModelFormSet
if not hasattr(self, '_queryset'):
self._queryset = self.queryset.filter(type__startswith='xyz'))
if not self._queryset.ordered:
self._queryset = self._queryset.order_by(self.model._meta.pk.name)
return self._queryset
答案 1 :(得分:0)
我相信在这种情况下,您需要在调用inlineformset_factory时使用 form 参数,并使用ad-hoc __init__
方法传递自定义表单。
如果你需要它是参数化的,我前段时间在这里找到了救生线
FormSetName.form = staticmethod(curry(FormName, customparam=chosenparam))
其中,如上所述,FormSetName是使用指向FormName的 form 参数定义的。
顺便说一下,我很乐意向那些提出上述解决方案的人表示赞赏,他会喜欢留下温暖的回复,但声誉太低。这将是自定义的表单类(在这种情况下,选择一个人作为亲戚,但只在一部分人中,由< em> relatives()方法):
class RelativeSelectForm(forms.ModelForm):
class Meta:
model = Person
fields = ('relative',)
def __init__(self, *args, **kwargs):
try:
profile = kwargs.pop('profile')
except KeyError:
super(RelativeSelectForm, self).__init__(*args, **kwargs)
return
super(RelativeSelectForm, self).__init__(*args, **kwargs)
self.fields['relative'].queryset = profile.relatives().order_by('name')
并且可以在 vies.py :
中使用它RelativesFormSet = inlineformset_factory(Person, Person, form=RelativeSelectForm, can_delete=True, extra=1)
RelativesFormSet.form = staticmethod(curry(RelativeSelectForm, profile=request.user.profile))
以便每次实例化一个表单集时,它会自动获取填充了正确对象的配置文件参数,而 relative 选择框的查询集仅显示他有权访问的人至。 希望我让自己更清楚一点:)