Фильтр Queryset в Django inlineformset_factory

Я пытаюсь использовать inlineformset_factory для создания набора форм. Мои модели определяются как:

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 новым набором запросов, но не мог понять, как правильно передать параметр эксперимента.

Обновленный ответ (я также включил здесь информацию как способ передать параметр в форму :

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)
+7
источник поделиться
2 ответа

(отредактируйте: не читайте коды кода правильно, вот должно быть решение вашей проблемы):

Я считаю, что вам нужно: 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
  )

Связывание с набором форм выполняется с использованием параметра формы.

+3
источник

У меня была одна и та же проблема (инициализация встроенных форм с ограниченными возможными значениями), а ответ "Обновленный" отлично работает. Спасибо за это. Во всяком случае, есть что-то, что можно было бы сделать лучше, я думаю, но я не знаю, как это сделать. Новая проблема в этом решении заключается в том, что вы попадаете в базу данных в каждой встроенной форме: вместо того, чтобы использовать один и тот же запрос во всех одинаковых полях, каждый раз пересчитывает его в этой строке:

 self.fields["subject"].queryset = Subject.objects.filter(experiment=experiment)

Я прав в этом вопросе, или есть какая-то ленивая джанго-магия за капюшоном? Если я прав, как я могу избежать (возможной сотни) хитов в БД? Приветствую, Педро

+1
источник

Посмотрите другие вопросы по меткам или Задайте вопрос