@MAGistr_MTM
Учусь программировать

Как изменить queryset для ModelChoiceField на форме?

Доброго времени суток.

У меня есть две модели(кроме остальных и упрощено):
class Range(AbstractRange):
    site = models.ManyToManyField(Site)

class ConditionalOffer(AbstractConditionalOffer):
    site = models.ForeignKey(Site, null=True)
    range = models.ForeignKey(Range, null=True)

Еще у меня есть две формы для ConditionalOffer, на каждой из которых есть поле ModelChoiceField. На первой форме выбирается поле Site, а на второй Range. Нужно сделать так, что бы на второй форме можна было выбрать только те Range, в которых поле Site имеет значение поля Site первой формы.

Вот примеры форм:
class MetaDataForm(OscarMetaDataForm):
    site = forms.ModelChoiceField( 
        queryset=Site.objects.all(),
        widget=SITE_WIDGET,
        initial=SITE_INITIAL)

    class Meta:
        model = ConditionalOffer
        fields = ('site', 'name', 'description')


class BenefitForm(OscarBenefitForm):
    range = forms.ModelChoiceField( 
        queryset=Range.objects.filter(site__id=settings.SITE_ID)

    class Meta:
        model = Benefit
        fields = ('range', 'type', 'value', 'max_affected_items')

Тоесть мне нужно вместо settings.SITE_ID в строке
queryset=Range.objects.filter(site__id=settings.SITE_ID)
поставить ID выбраного сайта из первой формы.

Как мне это сделать? Буду очень благодарен за помощь.
  • Вопрос задан
  • 2092 просмотра
Решения вопроса 1
winordie
@winordie
Лучшая документация -- исходники
Мне кажется проще всего при изменении поля site первой формы отправлять ajax запрос с выбранными site_id. Для BenefitForm сделать что то по типу:
class BenefitForm(OscarBenefitForm):
    range = forms.ModelChoiceField()
    def __init__(self, *args, **kwargs):
        super(BenefitForm, self).__init__(*args, **kwargs)
        if hasattr(kwargs, 'site_ids'):
            self.fields['range'].queryset = Range.objects.filter(site__id__in=kwargs.get('site_ids'))
        else:
            self.fields['range'].queryset = Range.objects.all()

В ответе получать отрендеренную форму и вставлять ее на страницу.

Либо изначально получать все Range, а уже с помощью js отфильтровывать.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы