在Django inlineformset中过滤Queryset
我正在尝试使用inlineformset_factory生成一个formset。 我的模型被定义为:
class Measurement(models.Model):
subject = models.ForeignKey(Subject)
experiment = models.ForeignKey(Experiment)
assay = models.ForeignKey(Assay)
values = models.CommaSeparatedIntegerField(blank=True, null=True)
class Experiment(models.Model):
date = models.DateField()
notes = models.TextField(max_length = 500, blank=True)
subjects= models.ManyToManyField(Subject)
在我看来,我有:
def add_measurement(request, experiment_id):
experiment = get_object_or_404(Experiment, pk=experiment_id)
MeasurementFormSet = inlineformset_factory(Experiment, Measurement, extra=10, exclude=('experiment'))
if request.method == 'POST':
formset = MeasurementFormSet(request.POST,instance=experiment)
if formset.is_valid():
formset.save()
return HttpResponseRedirect( experiment.get_absolute_url() )
else:
formset = MeasurementFormSet(instance=experiment)
return render_to_response("data_entry_form.html", {"formset": formset, "experiment": experiment }, context_instance=RequestContext(request))
但我想限制Measurement.subject字段仅限于Experiment.subjects查询集中定义的主题。 我尝试了几种不同的方式来做到这一点,但我有点不确定要达到这个目的的最佳方法。 我尝试用新的查询集覆盖BaseInlineFormset类,但无法弄清楚如何正确传递实验参数。
更新了答案 (我还包括了来自这里的信息,作为将参数传递给formset链接的一种方式):
views.py
def add_measurement(request, experiment_id):
experiment = get_object_or_404(Experiment, pk=experiment_id)
MeasurementFormSet = inlineformset_factory(Experiment, Measurement, extra=10, can_delete=True, form=MeasurementForm)
MeasurementFormSet.form = staticmethod(curry(MeasurementForm, experiment=experiment))
if request.method == 'POST':
formset = MeasurementFormSet(request.POST)
if formset.is_valid():
formset.save()
return HttpResponseRedirect( experiment.get_absolute_url() )
else:
formset = MeasurementFormSet()
return render_to_response("data_entry_form.html", {"formset": formset, "experiment": experiment }, context_instance=RequestContext(request))
forms.py
class MeasurementForm(ModelForm):
class Meta:
model = Measurement
def __init__(self, *args, **kwargs):
experiment = kwargs.pop('experiment')
super(MeasurementForm, self).__init__(*args, **kwargs)
self.fields["subject"].queryset = Subject.objects.filter(experiment=experiment)
(编辑:没有正确阅读代码块,这里应该是你的问题的解决方案):
我相信你需要:http://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield
Forms.py:
class MeasurementForm(ModelForm):
subject = forms.ModelChoiceField(queryset = Expirement.objects.all())
class Meta:
model = Measurement
Views.py:
inlineformset_factory(
Experiment, Measurement, extra=10,
exclude=('experiment'), form=MeasurementForm
)
绑定到formset是使用表单参数完成的。
我是通过相同的问题(初始化inlineforms与有限的可能值),并且更新的答案很好。 感谢那。 无论如何,我认为有些事情可以做得更好,但我不知道如何做到这一点。 该解决方案中的新问题是,您在每个内联表单中都要打开数据库:而不是在所有相同的字段中使用相同的查询集,每次在此行中重新计算它:
self.fields["subject"].queryset = Subject.objects.filter(experiment=experiment)
我在这个问题上是正确的还是在背后隐藏着一些懒惰的django魔法? 如果我是对的,我怎样才能避免(数百)命中数据库? 问候,佩德罗
链接地址: http://www.djcxy.com/p/45291.html上一篇: Filter Queryset in Django inlineformset
下一篇: How often do you create implicit conversions for your classes?