wogsland
wogsland

Reputation: 9518

Django Admin Form Limit Dropdown Options

So in the Django admin I have an object change form like so:

class SurveyChoiceField(forms.ModelChoiceField):
    def label_from_instance(self, obj):
        return u'{0} - {1}'.format(obj.id, obj.name)


class BlahAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BlahAdminForm, self).__init__(*args, **kwargs)
        surveys = Survey.objects.filter(deleted=False).order_by('-id')
        self.fields['survey'] = SurveyChoiceField(queryset=surveys)


class BlahAdmin(admin.ModelAdmin):
    form = BlahAdminForm

and I would like to limit the dropdown to surveys of a certain type based on the blah. Something like

blah_id = self.blah.id
blah_survey_type = Blah.objects.filter(id=blah_id).get('survey_type')
surveys = Survey.objects.filter(deleted=False, type=blah_survey_type).order_by('-id')

but I'm not sure how to get the id of the Blah in the BlahAdminForm class.

Upvotes: 2

Views: 428

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477533

A Django ModelForm has an instance which is the Blah instance it will create or edit. In case you edit an instance, the instance is passed through the instance parameter when creating the form. In case you create a new instance, then the instance is typically constructed in the super(BlahAdminForm, self).__init__(..) call (but has an id equal to None, since it is not yet saved).

You thus can obtain a reference to the instance that the form is editing, or a its id with:

class BlahAdminForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BlahAdminForm, self).__init__(*args, **kwargs)
        blah_id = self.instance.id
        # ...

You can thus use this self.instance in the constructor, or in other methods to inspect (and alter) the instance the form is handling.

Upvotes: 2

Related Questions