Django filter Выбор поля ModelFormSet… отличается от ограничения набора запросов Formset

Я понимаю, что можно переопределить набор запросов по умолчанию, «используемый» набором моделей . Это просто ограничивает объекты, для которых создается форма.

Я также нашел вопрос о переполнении стека о фильтрации вариантов ForeignKey в Django ModelForm , но не ModelForm Set и о ограничении доступных вариантов в наборе форм Django , но не Model FormSet. Я включил свою версию этого кода ниже.

Я хочу отрендерить ModelFormSet для школьного класса ('обучающая группа' или 'theclass', чтобы избежать конфликта с ключевым словом 'class') с одним полем, ограниченным набором запросов. Это необходимо для формы редактирования класса учителем, чтобы иметь возможность переназначить учеников в другой класс, но ограничено классами в той же когорте.

My models.py

class YearGroup(models.Model):
    intake_year = models.IntegerField(unique=True)
    year_group = models.IntegerField(unique=True, default=7)
    def __unicode__(self):
        return u'%s (%s intake)' % (self.year_group, self.intake_year)

    class Meta:
        ordering = ['year_group']

class TeachingGroup(models.Model):
    year = models.ForeignKey(YearGroup)
    teachers = models.ManyToManyField(Teacher)
    name = models.CharField(max_length=10)
    targetlevel = models.IntegerField()
    def __unicode__(self):
        return u'Y%s %s' % (self.year.year_group, self.name)

    class Meta:
        ordering = ['year', 'name']

My views.py

def edit_pupils(request, teachinggroup):
    theclass = TeachingGroup.objects.get(name__iexact = teachinggroup)
    pupils = theclass.pupil_set.all()

    PupilModelFormSet = modelformset_factory(Pupil)

    classes_by_year = theclass.year.teachinggroup_set.all()
    choices = [t for t in classes_by_year]
#    choices = [t.name for t in classes_by_year] #### I also tried this

    if request.method == 'POST':
        formset = PupilModelFormSet(request.POST,queryset=pupils)
        if formset.is_valid():
            formset.save()
            return redirect(display_class_list, teachinggroup = teachinggroup)
    else:
        formset = PupilModelFormSet(queryset=pupils)
        for form in formset:
            for field in form:
                if 'Teaching group' == field.label:
                    field.choices = choices


    return render_to_response('reassign_pupils.html', locals())

Как видите, я ограничиваю выбор набором запросов classes_by_year, который представляет собой только классы, принадлежащие к той же группе года. Этот набор запросов выводится правильно, как вы можете видеть на отрисованной странице ниже, но он вообще не влияет на поле формы.

Мой шаблон

{% for form in formset %}

    {% for field in form.visible_fields %}
                {# Include the hidden fields in the form #}
        {% if forloop.first %}
            {% for hidden in form.hidden_fields %}
            {{ hidden }}
            {% endfor %}
        {% endif %}
        

{{ field }} {% if field.errors %}

{{field.errors|striptags}}

{% endif %} {% endfor %} {% endfor %}

{{ choices }}

Страница отображается со всеми обучающими группами (классами), видимыми в виджете выбора, но тег внизу страницы отображается как: [, ] , точно показывающий только два класса в 8 классе.

Обратите внимание, что я также прочитал сообщение Джеймса Беннета Итак, вам нужна динамическая форма , как рекомендовано Как я могу ограничить доступные варианты для поля внешнего ключа в django modelformset? , но это требует изменения метода __ init __ в формах.py, и все же единственный способ, которым я знаю, как создать ModelFormSet, - это modelformset_factory, который не включает определение каких-либо классов в forms.py.

В дополнение к помощи Люка Снирингера , вот моя новая запись forms.py. После прочтения Почему я получаю ошибку «Не повторяется объект»? Я понял, что некоторые из моих проблем возникли из-за передачи кортежа методу field.choices, когда он ожидал словарь. Вместо этого я использовал подход .queryset, и он отлично работает:

class PupilForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(PupilForm, self).__init__(*args, **kwargs)
        thepupil = self.instance
        classes_by_year = thepupil.teaching_group.year.teachinggroup_set.all()
        self.fields['teaching_group'].queryset = classes_by_year

class Meta:
    model = Pupil

7
задан Community 23 May 2017 в 12:17
поделиться