2012-10-20 7 views
11

Ich habe ein Feld in einem meiner Modelle wie folgt aus:Wie ändert man die leere_Label für das ModelForm-Auswahlfeld?

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

Wenn ich ein Modell für diesen Bereich erstellen, Django erzeugt korrekt ein HTML-Select-Box, enthält aber einen leeren Standardwert „- ------- ".

Ich würde gerne wissen, wie Sie diesen Standardwert auf einen anderen Text, wie "Bitte wählen Sie Wert" ändern.

Ich glaube, ich sollte diese in der Lage sein zu setzen in meinem Modell init über das folgende Formular, wie in this answer und mehrere andere dokumentiert:

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

Doch diese Arbeit ist nicht für mich. Wenn ich diese Zeile in das Formular init meines Formulars einfüge, erscheint "--------" immer noch als erste Wahl in der Auswahlbox. Ich füge die relevanten forms.py unten ein, aber es scheint, dass andere also been unable to access/modify empty_label haben. Unter diesem Link beschreibt der Fragesteller, einen Weg zu den Standard empty_label Wert löschen (was ich konnte erfolgreich über seine Methode tun), aber was ich wirklich will ist zu tun die empty_label ändern, die angezeigt wird.

Irgendwelche Ideen?

Hier ist der Code für das Formular in forms.py, mit dem empty_label-Code, der auf eine Änderung der Standardeinstellung "----------" nicht erfolgreich ist:

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(), 
    } 

Antwort

5

Das Problem ist, dass Sie etwas geben versuchen, die für die Art der Auswahl nicht verfügbar ist Feld.

Die Option empty_label ist für forms.ModelChoiceField, die zufällig ein Select-Widget verwendet, aber nicht dasselbe Feld wie Ihr CharField, für das Sie Optionen bereitstellen.

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

Sie können dies auch in einer früheren Frage hier: https://stackoverflow.com/a/740011/1406860

Sie könnten versuchen, den HTML-Code des Modelform überschreiben die erste Option als „wählen Sie bitte Wert“ hinzuzufügen. Alternativ können Sie einen Vorlagenfilter verwenden, um dasselbe zu tun. Zuletzt könnten Sie und ("", "Bitte wählen Sie den Wert") zu PAYROLL_CHOICES, und wenn Sie nicht möchten, dass es ohne einen PayrollProvider eingereicht wird, setzen Sie einfach blank = False für das Feld im Modell.

JD

+0

Dank ! Sehr geschätzt. – CQP

1

Nur ModelChoiceField (generiert für ForeignKey Felder) unterstützt die empty_label Parameter, und in diesem Fall ist es schwierig zu bekommen, wie diese Felder in der Regel von innerhalb eines Aufrufs an django.forms.models.modelform_factory generiert werden.

ModelFormMetaclass verwendet die empty_label param eine andere Wahl in der Liste hinzuzufügen, mit empty_label als Display und '' als Wert.

Die einfachste Art und Weise zu tun, was Sie wollen, ist nur eine leere Auswahl in Ihre Auswahlliste hinzuzufügen:

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

     etc..... 
        ) 
8

Dokkaebi, das wird nicht richtig funktionieren.

<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> 

Die einzige relativ bequeme Art und Weise, die mir in den Sinn kam, ist so etwas wie dies in Form zu tun: Sie werden die folgenden wählen Code

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

Ein Lebensretter nach 3 Stunden mit dem Kopf gegen eine Wand hämmern. Das Ändern des leeren Etiketts scheint in 1.7 möglich zu sein. –

5

Eigentlich jetzt (wie von Django1.8 und höher) Überschreibung eines empty_label Werke:

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

Auch, wenn Sie mit Django Admin arbeiten, gibt es eine Option leeren Wert für eine Listenansicht zu setzen:

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

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

Was passiert, wenn Feld readonly sein sollte?

Es gibt einen Haken, wenn Feld so geändert werden sollte readonly sein.

Wenn außer Kraft gesetzt Formularfeld wird in readonly_fields Attributen innerhalb PayrollCredentialAdmin Klasse angegeben werden, es in KeyError Ausnahme in PayrollCredentialForm führen würde (weil readonly Feld wird nicht in Form des enthält self.fields). Um dies zu umgehen, ist es erforderlich formfield_for_dbfield statt mit readonly_fields außer Kraft zu setzen:

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 

könnte nützlich sein.


Update für Django1.11:

Kommentare unten gebracht Annahme, dass solche Überschreibung nicht für neuere Version von Django mehr gültig ist.

+0

Doesnt Arbeit für mich auf Django 1.9.7 – Julian

+0

Seltsam, es funktionierte für mich auf Django 1.9 (nicht speziell 1.9.7 obwohl getestet). Upvotes bestätigte, dass dies eine funktionierende Lösung ist. Vielleicht hast du irgendwo im Code einen Fehler gemacht? – Nevertheless

+0

Können Sie das gesamte Formular (einschließlich des von Ihnen verwendeten Feldes) als Vergleich einreichen? Ich habe es über das Hinzufügen einer leeren Auswahl gelöst, aber es ist irgendwie ärgerlich, da ModelChoice diese Option hat (und es funktioniert) – Julian

1

In Ihrer forms.py Datei, Dies würde dies auf jeden Fall arbeiten .. Versuchen ...

 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' 

Es funktionierte für mich .. nur mit Ihnen die Feldnamen ersetzen ...

Verwandte Themen