web-dev-qa-db-fra.com

Comment ajouter des attributs de classe, id, espace réservé à un champ dans les formulaires Django model

J'ai un modèle Django comme ci-dessous

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

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

product_form.py (juste un exemple)

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

En fait, je veux afficher/rendre la sortie html comme ci-dessous

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

Alors, enfin, comment ajouter des attributs (id, espace réservé, classe) aux champs du formulaire modèle dans le code ci-dessus?

35

Vous pouvez effectuer les opérations suivantes:

#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'})
45
Alex Parakhnevich

Les identifiants de champ doivent être générés automatiquement par Django, pour remplacer les autres champs:

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'
            })
27
mariodev

J'aime vraiment la réponse de Dmitriy Sintsov, mais cela ne fonctionne pas. Voici une version qui fonctionne:

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

mise à jour

ajouter cette condition pour mieux

if self.fields[field].widget.__class__.__in ('AdminTextInputWidget' , 'Textarea' , 'NumberInput' , 'AdminURLFieldWidget', 'Select'): 
     self.fields[field].widget.attrs.update({ 'class': 'form-control' })
23
Derick Hayes

Vous pouvez mettre à jour forms.py comme ci-dessous

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'}),
                }  
15
kali sharma

Version légèrement modifiée de l'excellente réponse mariodev, ajoutant bootstrap classe à tous les champs de formulaire, donc je n'ai pas à recréer manuellement les widgets d'entrée de formulaire pour chaque champ (short Python 3.x super ()):

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

En ajoutant à la réponse de Derick Hayes j'ai créé une classe BasicForm qui étend les formulaires. ModelForm qui ajoute les classes bootstrap à chaque formulaire qui l'étend).

Pour mes formulaires, j'étends simplement BasicForm au lieu du formulaire modèle et j'obtiens automatiquement les classes bootstrap sur tous les formulaires.

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
        })
3
hurlbz

filtre add_class pour ajouter une classe CSS au champ de formulaire:

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

bibliothèque Django-widget-tweaks

3
Sunny Multani

Vous pouvez effectuer les opérations suivantes:

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