2012-10-20 15 views
11

Ho un campo in uno dei miei modelli come la seguente:Come modificare empty_label per il campo di scelta modelForm?

payrollProvider = models.CharField(max_length=2, choices=PAYROLL_CHOICES) 
PAYROLL_CHOICES = (
     ('C1', 'Choice1'), 
     ('C2', 'Choice2') 
     etc..... 
        ) 

Quando creo un modulo standard per questo campo, Django genera correttamente un select box HTML, ma include un valore vuoto di default "- -------".

Vorrei sapere come modificare questo valore predefinito in un altro testo, ad esempio "scegliere il valore".

credo che dovrei essere in grado di impostare questo in init di mia forma modello tramite il seguente, come documentato in this answer e molti altri:

self.fields['payrollProvider'].empty_label = "please choose value" 

Tuttavia, questo non funziona per me. Quando includo quella linea nel init del mio modulo, "--------" appare ancora come scelta iniziale nella casella di selezione. Sto incollando la relativa forma.py sotto, ma sembra che altri abbiano also been unable to access/modify empty_label. A questo link, l'interrogante descrive un modo per eliminare il valore predefinito empty_label (che ero in grado di fare con successo attraverso il suo metodo) ma quello che voglio veramente fare è modificare the empty_label che viene visualizzato.

Qualche idea?

Ecco il codice per il modulo in forms.py, con il codice empty_label che non è riuscita a cambiare il valore di default "----------":

class PayrollCredentialForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(PayrollCredentialForm, self).__init__(*args, **kwargs) 
     self.fields['payrollUsername'].widget.attrs.update({'class' : 'yp-signup'}) 
     self.fields['payrollPassword'].widget.attrs.update({'class' : 'yp-signup'}) 
     self.fields['payrollProvider'].widget.attrs.update({'class' : 'yp-signup'}) 
     self.fields['payrollUsername'].widget.attrs.update({'placeholder' : ' Payroll Username'}) 
     self.fields['payrollPassword'].widget.attrs.update({'placeholder' : ' Payroll Password'}) 
     self.fields['payrollProvider'].empty_label = "please choose value" 


class Meta: 
    model = Company 
    fields = ('payrollProvider', 'payrollUsername', 'payrollPassword') 
    widgets = { 
     'payrollPassword': forms.PasswordInput(), 
    } 

risposta

5

Il problema è che si sta tentando di indicare qualcosa che non è disponibile per il tipo di Select campo.

L'opzione empty_label è per forms.ModelChoiceField, che si verifica utilizzando un widget Seleziona, ma non è lo stesso tipo di campo del CharField per il quale si forniscono opzioni.

https://docs.djangoproject.com/en/dev/ref/forms/fields/#modelchoicefield

Si può vedere questo anche in una domanda precedente qui: https://stackoverflow.com/a/740011/1406860

Si potrebbe cercare di ignorare il codice html della ModelForm per aggiungere la prima opzione come "si prega di scegliere il valore". In alternativa, puoi usare un filtro modello per fare la stessa cosa. Infine, è possibile e ("", "scegliere il valore") su PAYROLL_CHOICES e, se non si desidera che venga inviato senza un libro pagaProvider, è sufficiente impostare blank = False per il campo nel modello.

JD

+0

Grazie ! Molto apprezzato. – CQP

1

Solo ModelChoiceField (generato per i campi ForeignKey) supporta il parametro empty_label e in tal caso è difficile da ottenere poiché tali campi vengono generalmente generati da django.forms.models.ModelFormMetaclass all'interno di una chiamata a django.forms.models.modelform_factory.

ModelFormMetaclass utilizza il empty_label param per aggiungere un'altra scelta per la lista, con empty_label come il display e '' come valore.

Il modo più semplice per fare ciò che si vuole è solo per aggiungere una scelta vuoto alla tua lista scelte:

PAYROLL_CHOICES = (
     ('', 'please choose value'), 
     ('C1', 'Choice1'), 
     ('C2', 'Choice2'), 

     etc..... 
        ) 
8

dokkaebi, che non funzionerà correttamente. Riceverai il seguente codice selezionare:

<select name="payrollProvider" id="id_payrollProvider"> 
<option value="" selected="selected">---------</option> 
<option value="" selected="selected">please choose value</option> 
<option value="C1">Choice1</option> 
<option value="C2">Choice2</option> 
</select> 

L'unico modo relativamente conveniente che mi è venuta in mente è quello di fare qualcosa di simile nella forma:

class PayrollCredentialForm(forms.ModelForm): 
    class Meta: 
     model = Company 
    def __init__(self, *args, **kwargs): 
     super(PayrollCredentialForm, self).__init__(*args, **kwargs) 
     self.fields["payrollProvider"].choices = [("", "please choose value"),] + list(self.fields["payrollProvider"].choices)[1:] 
+1

Un vero toccasana dopo 3 ore di sbattere la testa contro un muro. Cambiare l'etichetta vuota sembra possibile in 1.7. –

5

In realtà, ora (come di Django1.8 e superiori) Azionamento di un empty_label opere:

class PayrollCredentialForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super(PayrollCredentialForm, self).__init__(*args, **kwargs) 
     self.fields['payrollProvider'].empty_label = 'Please, choose value' 

Inoltre, se si lavora con Django Admin, v'è la possibilità di impostare il valore di vuoto per una visualizzazione elenco:

class PayrollCredentialAdmin(admin.ModelAdmin): 
    list_display = ('payrollProvider_value',) 

    def payrollProvider_value(self, instance): 
     return instance.payrollProvider 
    payrollProvider_value.empty_value_display = 'Empty value' 

Cosa se il campo dovrebbe essere readonly?

C'è un problema se il campo modificato in questo modo deve essere readonly.

Se campo modulo ignorato sarà specificato in attributo readonly_fields all'interno PayrollCredentialAdmin classe, si tradurrebbe in KeyError eccezione PayrollCredentialForm (perché readonly campo non saranno inclusi nella forma di self.fields). Per gestire questo, è necessario eseguire l'override formfield_for_dbfield invece di utilizzare readonly_fields:

def formfield_for_dbfield(self, db_field, **kwargs): 
    field = super(PayrollCredentialAdmin, self).formfield_for_dbfield(
     db_field, **kwargs 
    ) 
    db_fieldname = canonical_fieldname(db_field) 

    if db_fieldname == 'payrollProvider': 
     field.widget = forms.Select(attrs={ 
      'readonly': True, 'disabled': 'disabled', 
     }) 

    return field 

potrebbe essere utile.


Aggiornamento per Django1.11:

commenti qui sotto ipotesi portato che tale esclusione non è più valida per la versione più recente di Django.

+0

Non funziona per me su django 1.9.7 – Julian

+0

Strano, ha funzionato per me su Django 1.9 (non testato in particolare 1.9.7). Upvotes ha confermato che si tratta di una soluzione funzionante. Forse hai fatto un errore da qualche parte nel codice? – Nevertheless

+0

Puoi postare l'intero modulo (incluso il campo che hai usato) per il comparsion? L'ho risolto aggiungendo una scelta vuota ma è fastidioso dal momento che ModelChoice ha questa opzione (e funziona) – Julian

1

Nel file forms.py, Questo sarebbe sicuramente lavorare .. Prova questo ...

 class Meta: 
     model = StaffDetails 
     fields =['photo','email', 'first_name','school','department', 'middle_name','last_name','gender', 'is_active'] 
    def __init__(self, *args, **kwargs): 
     super(StaffDetailsForm, self).__init__(*args, **kwargs) 
     self.fields['Field_name'].empty_label = 'Please Select' 

Ha funzionato per me .. basta sostituire i nomi dei campi con il tuo ...

Problemi correlati