2011-03-16 12 views
48

Ho una classe definita Django Form piace questo in Models:Django ModelChoiceField: il filtraggio della query e l'impostazione valore predefinito come oggetto

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

Questo funziona bene, ma ha alcune limitazioni che non riesco a aggirare:

(1) Vorrei utilizzare un filtro sulla queryset, basata su una variabile accountid passata alla forma, in questo modo:

User.objects.filter(account=accountid) 

Questo non può funzionare nel modello perché non è possibile passare a accountid come variabile, ovviamente.

Ne consegue che lo queryset deve in qualche modo essere definito nello Views, ma per quanto posso vedere è un campo obbligatorio nella classe Form.

(2) Vorrei fare la scelta predefinita di AccountDetailsForm un oggetto nel database, che posso selezionare nella Views come questo:

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

ho provato specificando l'adminuser come default il valore nella forma, (che lavora con altri campi del modulo standard, come 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}) 

ma senza fortuna.

Devo usare qualcosa di diverso da ModelChoiceField data la flessibilità di cui ho bisogno qui?

Grazie.

risposta

91

override del metodo init e accettare un nuovo argomento parola chiave

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) 

Si può sempre e solo impostare le scelte manualmente nella vista pure.

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

attenzione: siete non valori impostazione di default, passando in un dizionario per una forma come nel tuo esempio.

In realtà stai creando un modulo associato, potenzialmente attivando la convalida e tutto il jazz.

Per impostare i valori predefiniti, use the initials argument.

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

Ciao, grazie per la risposta. L'impostazione del queryset nella vista ha funzionato bene. La parte che non ho potuto elaborare è impostare il valore del modulo associato (anziché predefinito) di ModelChoiceField come _User.objects.filter (account = accountid) .filter (primary_user = 1) _. Grazie. – eli

6

È possibile ignorare il campo nella visualizzazione

yourForm = AccountDetailsForm() 

yourForm.fields['accomodation'] = forms.ModelChoiceField(User.objects.filter(account=accountid).filter(primary_user=1)) 
Problemi correlati