web-dev-qa-db-fra.com

Changer la largeur des éléments de formulaire créés avec ModelForm dans Django

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 réel ...

50
Josh Hunt

Le moyen le plus simple pour votre cas d'utilisation est d'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 formulaire de formulaire (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

C'est décrit dans la documentation de Django .

Troisième approche consiste à laisser l'interface déclarative Nice de newforms pendant un certain temps et à définir vos attributs de 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.
105
zuber

Excellente réponse de zuber, mais je crois qu'il y a une erreur dans l'exemple de code pour la troisième approche. Le constructeur devrait ê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.

15
bryan

Si vous utilisez un module complémentaire tel que Grappelli qui utilise beaucoup de styles, vous constaterez peut-être que tous 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 lors de l'utilisation de l'excellente deuxième ou troisième approche de zuber ci-dessus.

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

Voici un exemple modifiant 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;'
6
bergdesign

Définissez row et votre classe css dans votre vue de modèle d'administration:

'explicacion': AutosizedTextarea(attrs={'rows': 5, 'class': 'input-xxlarge', 'style': 'width: 99% !important; resize: vertical !important;'}),
0
Cubiczx