Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
437 views
in Technique[技术] by (71.8m points)

Django ModelChoiceField: filtering query set and setting default value as an object

I have a Django Form class defined likes this in Models:

class AccountDetailsForm(forms.Form):
    ...
    adminuser = forms.ModelChoiceField(queryset=User.objects.all())

This works OK, but it has some limitations I can't seem to work around:

(1) I would like to use a filter on the queryset, based on a variable accountid passed to the form, like this:

User.objects.filter(account=accountid)

This can't work in the model because accountid can't be passed as a variable, of course.

It follows that the queryset must somehow be defined in the Views, but as far as I can see it's a required field in the Form class.

(2) I would like to make the default choice of AccountDetailsForm an object in the database, which I can select in the Views like this:

User.objects.filter(account=accountid).filter(primary_user=1)

I've tried specifying the adminuser as a default value in the form, (which works with other standard form fields, like CharField):

adminuser = User.objects.filter(account=accountid).filter(primary_user=1)

...

form = AccountDetailsForm({'adminuser': adminuser})
return render_to_response('accounts/edit/accountdetails.html', 
{'form': form, 'account':account})

But no luck.

Should I be using something other than ModelChoiceField given the flexibility I need here?

Thanks.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Override the init method and accept a new keyword argument

class AccountDetailsForm(forms.Form):
    ...
    adminuser = forms.ModelChoiceField(queryset=User.objects.all())
    def __init__(self, *args, **kwargs):
        accountid = kwargs.pop('accountid', None)
        super(AccountDetailsForm, self).__init__(*args, **kwargs)

        if accountid:
            self.fields['adminuser'].queryset = User.objects.filter(account=accountid)

form = AccountDetailsForm(accountid=3)

You can always just set the choices manually in the view as well.

form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)

Be warned: you are not setting default values by passing in a dictionary to a form like in your example.

You are actually creating a Bound Form, potentially triggering validation and all that jazz.

To set defaults, use the initials argument.

form = AccountDetailsForm(initial={'adminuser':'3'})

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...