Question

Comment puis-je changer la largeur d'un élément de formulaire textarea si j'ai utilisé ModelForm pour le créer?

Voici ma classe de produits:

class ProductForm(ModelForm):
    long_desc = forms.CharField(widget=forms.Textarea)
    short_desc = forms.CharField(widget=forms.Textarea)
    class Meta:
        model = Product

Et le code du modèle ...

{% for f in form %}
    {{ f.name }}:{{ f }}
{% endfor %}

f est l'élément de formulaire actuel ...

Était-ce utile?

La solution

Pour votre cas d'utilisation, le moyen le plus simple consiste à utiliser CSS . C'est un langage destiné à définir la présentation. Examinez le code généré par le formulaire, notez les identifiants des champs qui vous intéressent et modifiez l’apparence de ces champs via CSS.

Exemple pour le champ long_desc dans votre ProductForm (lorsque votre formulaire n'a pas de préfixe personnalisé):

#id_long_desc {
    width: 300px;
    height: 200px;
}

La deuxième approche consiste à transmettre le mot clé attrs au constructeur de votre widget.

class ProductForm(ModelForm):
    long_desc = forms.CharField(widget=forms.Textarea(attrs={'cols': 10, 'rows': 20}))
    short_desc = forms.CharField(widget=forms.Textarea)
    class Meta:
        model = Product

Il est décrit dans la documentation Django .

La troisième approche consiste à laisser l’interface déclarative de newforms pendant un moment et à définir les attributs de votre widget dans un constructeur personnalisé.

class ProductForm(ModelForm):
    long_desc = forms.CharField(widget=forms.Textarea)
    short_desc = forms.CharField(widget=forms.Textarea)
    class Meta:
        model = Product

    # Edit by bryan
    def __init__(self, *args, **kwargs):
        super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
        self.fields['long_desc'].widget.attrs['cols'] = 10
        self.fields['long_desc'].widget.attrs['rows'] = 20

Cette approche présente les avantages suivants:

  • Vous pouvez définir des attributs de widget pour les champs générés automatiquement à partir de votre modèle sans redéfinir des champs entiers.
  • Cela ne dépend pas du préfixe de votre formulaire.

Autres conseils

Excellente réponse de zuber, mais je crois qu’il existe une erreur dans l’exemple de code de la troisième approche. Le constructeur doit être:

def __init__(self, *args, **kwargs):
    super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
    self.fields['long_desc'].widget.attrs['cols'] = 10
    self.fields['long_desc'].widget.attrs['cols'] = 20

Les objets de champ n'ont pas d'attributs "attrs", mais leurs widgets en ont.

Si vous utilisez un module complémentaire tel que Grappelli qui fait un usage intensif des styles, vous constaterez que les attributs de ligne et de col remplacés sont ignorés en raison des sélecteurs CSS agissant sur votre widget. Cela pourrait se produire lorsque vous utiliserez l'excellente deuxième ou troisième approche de zuber ci-dessus.

Dans ce cas, utilisez simplement la première approche combinée avec la deuxième ou la troisième approche en définissant un attribut "style" au lieu des attributs "lignes" et "cols".

Voici un exemple de modification de init dans la troisième approche ci-dessus:

def __init__(self, *args, **kwargs):
    super(ProductForm, self).__init__(*args, **kwargs) # Call to ModelForm constructor
    self.fields['short_desc'].widget.attrs['style'] = 'width:400px; height:40px;'
    self.fields['long_desc'].widget.attrs['style']  = 'width:800px; height:80px;'

Définissez la ligne et votre classe CSS dans votre vue modèle administrateur:

'explicacion': AutosizedTextarea(attrs={'rows': 5, 'class': 'input-xxlarge', 'style': 'width: 99% !important; resize: vertical !important;'}),
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top