簡體   English   中英

在Django inlineformset_factory中過濾Queryset

[英]Filter Queryset in Django inlineformset_factory

我試圖使用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)

我在這個問題上是對的還是引擎蓋后面還有一些懶惰的魔法? 如果我是對的,我怎么能避免DB的可能百分之一? 問候,佩德羅

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM