Y
Y
Yura Khlyan2016-01-05 13:42:28
Django
Yura Khlyan, 2016-01-05 13:42:28

How to change queryset for ModelChoiceField on form?

Good day.
I have two models(besides the rest and simplified):

class Range(AbstractRange):
    site = models.ManyToManyField(Site)

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

I also have two forms for ConditionalOffer, each with a field ModelChoiceField. On the first form, the field is selected Site, and on the second Range. It is necessary to make it so that on the second form it would be possible to select only those Rangein which the field Sitehas the value of the field of the Sitefirst form.
Here are examples of forms:
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')

That is, I need instead settings.SITE_IDof in line
queryset=Range.objects.filter(site__id=settings.SITE_ID)
put the ID of the selected site from the first form.
How can I do it? I will be very grateful for your help.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Oscar Django, 2016-01-05
@MAGistr_MTM

It seems to me that the easiest way is to send an ajax request with the selected site_id when changing the site field of the first form. For BenefitForm do something like this:

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()

In response, get the rendered form and insert it on the page.
Either initially get all the Range, and then filter using js.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question