Изменить ширину элементов формы, созданных с помощью ModelForm в Django - PullRequest
50 голосов
/ 21 сентября 2008

Как изменить ширину элемента формы textarea, если я использовал ModelForm для его создания?

Вот мой класс продуктов:

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

И код шаблона ...

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

f - фактический элемент формы ...

Ответы [ 4 ]

105 голосов
/ 21 сентября 2008

Самый простой способ для вашего случая использования - это использовать CSS . Это язык, предназначенный для определения представления. Посмотрите на код, сгенерированный формой, запишите идентификаторы полей, которые вас интересуют, и измените внешний вид этих полей с помощью CSS.

Пример для поля long_desc в ProductForm (если ваша форма не имеет собственного префикса):

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

Второй подход - передать ключевое слово attrs в конструктор виджета.

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

Это описано в документации Django .

Третий подход - ненадолго оставить красивый декларативный интерфейс новых форм и установить атрибуты виджета в пользовательском конструкторе.

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

Этот подход имеет следующие преимущества:

  • Вы можете определить атрибуты виджета для полей, которые генерируются автоматически из вашей модели без переопределения целых полей.
  • Это не зависит от префикса вашей формы.
15 голосов
/ 13 марта 2009

Отличный ответ от zuber, но я считаю, что в примере кода есть ошибка для третьего подхода. Конструктор должен быть:

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

Объекты Field не имеют атрибутов 'attrs', но их виджеты имеют.

6 голосов
/ 08 августа 2014

В случае, если вы используете надстройку типа Grappelli, которая интенсивно использует стили, вы можете обнаружить, что любые переопределенные атрибуты row и col игнорируются из-за селекторов CSS, действующих на ваш виджет. Это может произойти при использовании превосходного Второго или Третьего подхода Цубера, описанного выше.

В этом случае просто используйте первый подход, смешанный со вторым или третьим подходом, установив атрибут 'style' вместо атрибутов 'row' и 'cols'.

Вот пример изменения init в третьем подходе выше:

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 голосов
/ 02 марта 2018

Установите строку и ваш класс CSS в представлении модели администратора:

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