frlan
frlan

Reputation: 7260

Django: forms.ModelChoiceField based on pk of calling view

I'm looking for a way to filter contents of a forms.ModelChoiceField() by the pk of a calling view.

I have a class based view:

class StorageItemMergeView(FormView):
    form_class = MergeStorageItemsForm
    #.... 

which is using MergeStorageItemsForm, currently defined as:

class MergeStorageItemsForm(forms.Form):
    storageitem1 = forms.ModelChoiceField(queryset=StorageItem.objects.get(pk=self.kwargs["pk"]))

StorageItemMergeView is connected to an object, so I only want to offer objects, which are also connected. I tried to put kwargs to form definition in several variations as e.g.

storageitem1 = forms.ModelChoiceField(queryset=StorageItem.objects.get(pk=self.kwargs["pk"]))

kwargs seems not to be defined in this context.

Also I found, that found that it is possible to redefine __init__() on a modelForm to get something like that done

def __init__(self, user=None, **kwargs):
    super(MergeStorageItemsForm, self).__init__(**kwargs)
    #... 

This didn't do the trick. How is it possible to filter the options offered by a form based on request and/or object the corresponding view is called for?

My corresponding section of urls.py look like that

url(r'^storageitem/(?P<pk>[\w]+)/merge/$', login_required(
        StorageItemMergeView.as_view()), name='storage_item_merge'),

Upvotes: 1

Views: 584

Answers (1)

Aamir Rind
Aamir Rind

Reputation: 39659

You have to do that in __init__ method, like this:

class MergeStorageItemsForm(forms.Form):
    storageitem1 = forms.ModelChoiceField(queryset=StorageItem.objects.none())

    def __init__(self, *args, **kwargs):
        self.storage_pk = kwargs.pop('pk')
        super(MergeStorageItemsForm, self).__init__(*args, **kwargs)
        self.fileds['storageitem1'].queryset = StorageItem.objects.get(pk=self.storage_pk)

Upvotes: 2

Related Questions