2013-10-21 12 views
24

ich ein django Modell Wie Klasse, id, Platzhalter-Attribute zu einem Feld in django Modell hinzuzufügen bildet

models.py

class Product(models.Model): 
    name = models.CharField(max_length = 300) 
    description = models.TextField(max_length = 2000) 
    created = models.DateTimeField(auto_now_add = True) 
    updated = models.DateTimeField(auto_now = True) 

    def __unicode__(self): 
     return self.name 

forms.py

wie unten

haben
class ProductForm(ModelForm): 
    class Meta: 
     model = Product 
     exclude = ('updated', 'created') 

product_form.py (nur ein Beispiel)

<form enctype="multipart/form-data" action="{% url 'add_a_product' %}" method="post"> 
     <div id="name"> 
      {{form.name}} 
     </div> 
     <div id="description"> 
      {{form.description}} 
     </div> 
    </form> 

Eigentlich möchte ich unter

<input id="common_id_for_inputfields" type="text" placeholder="Name" class="input-calss_name" name="Name"> 

<input id="common_id_for_inputfields" type="text" placeholder="Description" class="input-calss_name" name="description"> 

So endlich die HTML-Ausgabe wie anzuzeigen/render wie Attribute (id, Platzhalter, Klasse) auf die Modellformularfelder in dem obigen Code hinzufügen?

Antwort

32

Sie können wie folgt vorgehen:

#forms.py 
class ProductForm(ModelForm): 
    class Meta: 
     model = Product 
     exclude = ('updated', 'created') 

    def __init__(self, *args, **kwargs): 
     super(ProductForm, self).__init__(*args, **kwargs) 
     self.fields['description'].widget = TextInput(attrs={ 
      'id': 'myCustomId', 
      'class': 'myCustomClass', 
      'name': 'myCustomName', 
      'placeholder': 'myCustomPlaceholder'}) 
+2

Das funktionierte gut für mich, mit der Ausnahme, dass sie alle Optionen aus meiner Select-Widget gelöscht. Ich fand heraus, dass Sie die Widget-Deklaration alle zusammen übergehen können und trotzdem ihre Attribute wie folgt setzen: 'self.fields ['description']. Widget.attrs = { 'id': 'myCustomId', 'Klasse': 'myCustomClass', 'name': 'myCustomName', 'Platzhalter': 'myCustomPlaceholder'} ' scheint auch ein bisschen sauberer für mich. – bjesus

+0

Wenn Sie Bootstrap-Klassen zu allen Formularen hinzufügen möchten, ohne jedes Mal den Konstruktor überschreiben zu müssen, lesen Sie bitte meine Antwort unten. – hurlbz

24

Feld-IDs automatisch von django werden sollte, in anderen Bereichen außer Kraft zu setzen:

class ProductForm(ModelForm): 
    class Meta: 
     model = Product 
     exclude = ('updated', 'created') 

    def __init__(self, *args, **kwargs): 
     super(ProductForm, self).__init__(*args, **kwargs) 
     self.fields['name'].widget.attrs\ 
      .update({ 
       'placeholder': 'Name', 
       'class': 'input-calss_name' 
      }) 
+0

Sollen IDs wirklich automatisch generiert werden? Sie können die ID auch überschreiben. –

+0

Sie können ID auch überschreiben (genau wie ich Ihnen gezeigt habe, können Sie jedes Attribut überschreiben), aber ich denke, es ist besser, django generierte IDs zu verwenden, außer Sie haben keine Kontrolle über sie (wie wenn Sie js von Drittanbietern verwenden Bibliotheken oder smth ..) – mariodev

+0

'form.fields' ??? es sollte 'self.fields' sein – suhailvs

11

Sie können aktualisieren forms.py wie unten

 class ProductForm(ModelForm): 
      class Meta: 
        model = Product 
        exclude = ('updated', 'created') 
        widgets={ 
         "name":forms.TextInput(attrs={'placeholder':'Name','name':'Name','id':'common_id_for_imputfields','class':'input-class_name'}), 
         "description":forms.TextInput(attrs={'placeholder':'description','name':'description','id':'common_id_for_imputfields','class':'input-class_name'}), 

        } 
1

Sie können Folgendes tun:

class ProductForm(ModelForm): 
    name = forms.CharField(label='name ', 
      widget=forms.TextInput(attrs={'placeholder': 'name '})) 
3

leicht modifizierte Version der ausgezeichneten mariodev Antwort, das Hinzufügen Bootstrap-Klasse für alle Formularfelder, so dass ich nicht für jedes Feld Formulareingabe Widgets neu erstellen manuell (kurzen Python 3.x super()):

class ProductForm(forms.ModelForm): 
    def __init__(self, *args, **kwargs): 
     super().__init__(*args, **kwargs) 
     for field in self.Meta.fields: 
      self.fields[field].widget.attrs.update({ 
       'class': 'form-control' 
      }) 
+2

Es funktioniert auch, wenn Sie "self.fields" anstelle von "self.Meta.fields" verwenden. – j4n7

19

Ich mag Dmitriy Sintsovs Antwort wirklich, aber es funktioniert nicht. Hier ist eine Version, die funktioniert:

def __init__(self, *args, **kwargs): 
    super().__init__(*args, **kwargs) 
    for field in iter(self.fields): 
     self.fields[field].widget.attrs.update({ 
      'class': 'form-control' 
    }) 
+0

Dies ist viel besser, als jedes Mal das gesamte Widget zu bilden. Ich habe eine Klasse BasicForm erstellt, die forms.ModelForm erweitert, die das tut. Ich erweitere einfach BasicForm anstelle des Modellformulars und erhalte automatisch Bootstrap-Klassen für alle Formulare. Ich ging noch einen Schritt weiter und füge die Klassen an jede benutzerdefinierte CSS-Klasse an, die vielleicht schon da ist. Siehe meine Antwort für ein Codebeispiel. – hurlbz

3

Hinzufügen von Derick Hayes zu beantworten ich eine Klasse Grundform geschaffen, die forms.ModelForm erstreckt, die die Bootstrap-Klassen zu jeder Form hinzufügt, es erstreckt.

Für meine Formulare ich einfach BasicForm anstelle von Modellform zu erweitern und automatisch Bootstrap-Klassen auf allen Formen zu erhalten. Ich ging noch einen Schritt weiter und füge die Klassen an jede benutzerdefinierte CSS-Klasse an, die vielleicht schon da ist.

class BaseModelForm(forms.ModelForm): 

def __init__(self, *args, **kwargs): 
    super(BaseModelForm, self).__init__(*args, **kwargs) 
    # add common css classes to all widgets 
    for field in iter(self.fields): 
     #get current classes from Meta 
     classes = self.fields[field].widget.attrs.get("class") 
     if classes is not None: 
      classes += " form-control" 
     else: 
      classes = "form-control" 
     self.fields[field].widget.attrs.update({ 
      'class': classes 
     }) 
1

add_class Filter eine CSS-Klasse für das Hinzufügen von Feld zu bilden:

{% load widget_tweaks %}  
    <form enctype="multipart/form-data" action="{% url 'add_a_product' %}" method="post"> 
       <div id="name"> 
        {{form.name|add_class:"input-calss_name"}} 
       </div> 
       <div id="description"> 
        {{form.description|add_class:"input-calss_name"}} 
       </div> 
      </form> 

django-widget-tweaks library