J'ai une classe Django Form définie comme ça dans Models
:
class AccountDetailsForm(forms.Form):
...
adminuser = forms.ModelChoiceField(queryset=User.objects.all())
Cela fonctionne bien, mais il a certaines limitations que je n'arrive pas à contourner:
(1) Je voudrais utiliser un filtre sur l'ensemble de requêtes, basé sur une variable accountid
passée au formulaire, comme ceci:
User.objects.filter(account=accountid)
Cela ne peut pas fonctionner dans le modèle car accountid
ne peut pas être passé en tant que variable, bien sûr.
Il s'ensuit que le queryset
doit en quelque sorte être défini dans le Views
, mais autant que je sache, c'est un champ obligatoire dans la classe Form.
(2) Je voudrais faire le choix par défaut de AccountDetailsForm
un objet dans la base de données, que je peux sélectionner dans le Views
comme ceci:
User.objects.filter(account=accountid).filter(primary_user=1)
J'ai essayé de spécifier l'administrateur en tant que valeur par défaut dans le formulaire (qui fonctionne avec d'autres champs de formulaire standard, comme 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})
Mais pas de chance.
Dois-je utiliser autre chose que ModelChoiceField
étant donné la flexibilité dont j'ai besoin ici?
Merci.
Substituez la méthode init et acceptez un nouvel argument de mot clé
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)
Vous pouvez également toujours définir les choix manuellement dans la vue.
form = AccountDetailsForm()
form.fields['adminuser'].queryset = User.objects.filter(account=accountid)
Soyez averti: vous ne définissez pas des valeurs par défaut en passant un dictionnaire à un formulaire comme dans votre exemple.
Vous créez en fait un formulaire lié, ce qui peut déclencher la validation et tout ce jazz.
Pour définir les valeurs par défaut, tilisez l'argument des initiales.
form = AccountDetailsForm(initial={'adminuser':'3'})
Vous pouvez remplacer le champ dans la vue
yourForm = AccountDetailsForm()
yourForm.fields['accomodation'] = forms.ModelChoiceField(User.objects.filter(account=accountid).filter(primary_user=1))
Dans Django 2.0 vous pouvez passer un objet (User
dans votre cas) du view
au form
comme ceci (vous devez récupérer obj de la DB en premier):
form = AccountDetailsForm(initial={'adminuser': adminuser})
Il vous donnera un objet sélectionné par défaut (répond à votre 2) question)