【问题标题】:Change the width of form elements created with ModelForm in Django在 Django 中更改使用 ModelForm 创建的表单元素的宽度
【发布时间】:2010-09-11 17:48:56
【问题描述】:

如果我使用 ModelForm 创建 textarea 表单元素,如何更改它的宽度?

这是我的产品类别:

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 是实际的表单元素...

【问题讨论】:

    标签: python html django django-forms django-templates


    【解决方案1】:

    您的用例最简单的方法是使用 CSS。它是一种用于定义演示的语言。查看表单生成的代码,记下您感兴趣的字段的 id,并通过 CSS 更改这些字段的外观。

    ProductForm 中long_desc 字段的示例(当您的表单没有自定义前缀时):

    #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
    

    我是described in Django documentation

    第三种方法是暂时离开漂亮的 newforms 声明式界面,并在自定义构造函数中设置小部件属性。

    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
    

    这种方法有以下优点:

    • 您可以为从模型自动生成的字段定义小部件属性,而无需重新定义整个字段。
    • 它不依赖于表单的前缀。

    【讨论】:

    • 选项 3 非常有用。也许该示例还可以表明不需要在 Form 中定义字段,但仍然可以覆盖自动通过的 Model 中定义的字段。
    【解决方案2】:

    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”属性,但它们的小​​部件有。

    【讨论】:

    • 这确实应该是一个编辑,而不是它自己的答案(使用 SO 模型更好),但是您没有足够的声誉来进行编辑...
    • 我已经合并了编辑,如果有人想投票,我们也可以保留这个答案。
    • 对不起,你是对的——我应该留下评论。下次我会做得更好:)
    【解决方案3】:

    如果您使用像 Grappelli 这样大量使用样式的插件,您可能会发现任何被覆盖的 row 和 col 属性都会因为 CSS 选择器作用于您的小部件而被忽略。当使用上述 zuber 出色的第二种或第三种方法时,可能会发生这种情况。

    在这种情况下,只需通过设置“样式”属性而不是“行”和“列”属性来将第一种方法与第二种或第三种方法混合使用。

    这是在上面的第三种方法中修改 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;'
    

    【讨论】:

    • 你也可以在 admin.py 中为 ModelAdmin 添加 css 类,我觉得这样会更简洁一些。 Grappelli 不使用 stock django admin 提供的 cols/rows 有点失望。
    • 有没有什么办法可以通过一行代码将特定的width 应用到表单中的所有字段,而不是一一明确地应用到它们?
    • 我能够使用这种方法自定义我的 django 登录表单的默认外观
    【解决方案4】:

    在管理模型视图中设置行和 css 类:

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

    【讨论】:

      猜你喜欢
      • 2017-10-04
      • 2015-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 2017-10-06
      相关资源
      最近更新 更多