2008-09-21 31 views
47

Comment puis-je modifier la largeur d'un élément de formulaire textarea si j'ai utilisé ModelForm pour le créer?Modifier la largeur des éléments de formulaire créés avec ModelForm dans Django

Voici ma classe de produit:

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 forme réelle ...

Répondre

100

La meilleure façon pour votre cas d'utilisation est d'utiliser CSS. C'est un langage destiné à définir la présentation. Regardez le code généré par le formulaire, prenez note des 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 ne dispose pas d'un préfixe personnalisé):

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

Deuxième approche est de passer le mot-clé attrs à votre constructeur 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 described in Django documentation.

Troisième approche est de laisser la belle interface déclarative de nouvelles formes pendant un certain temps et définir vos attributs de widget dans le 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 un widget attributs pour les champs qui sont 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.
+0

Le second a parfaitement fonctionné –

+2

Option 3 est très utile. Peut-être que l'exemple pourrait également montrer que les champs n'ont pas besoin d'être définis dans le formulaire, mais peut encore remplacer les champs définis dans le modèle qui passent automatiquement. –

15

Excellente réponse de zuber, mais je crois qu'il y a une erreur dans le code d'exemple pour 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 Champ n'ont aucun attribut 'attrs', mais leurs widgets le font.

+1

Cela devrait vraiment être une édition, plutôt que sa propre réponse (c'est mieux avec le modèle SO), mais vous n'avez pas la réputation suffisante pour faire des modifications ... –

+1

J'ai fusionné l'édition, nous pouvons garder cette réponse aussi si Quelqu'un veut voter. –

+2

Désolé, vous avez raison - j'aurais dû laisser un commentaire à la place. Je ferai mieux la prochaine fois :) – bryan

4

Dans le cas où vous utilisez un add-on comme Grappelli qui utilise intensément les styles, vous pouvez constater que tous les attributs de ligne et col surchargés sont ignorés en raison des sélecteurs CSS agissant sur votre widget. Cela peut arriver en utilisant l'excellente deuxième ou troisième approche de zuber ci-dessus.

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

Voici un exemple de modification initialisation 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;' 
+0

Vous pouvez également ajouter des classes CSS dans le admin.py pour le ModelAdmin, je pense que ce sera un peu plus propre. Un peu déçu que Grappelli n'utilise pas les cols/lignes que fournit l'admin django. – radtek

0

Set ligne et votre classe css dans votre vue du modèle d'administration:

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