【问题标题】:How to add class, id, placeholder attributes to a field in django model forms如何将类、id、占位符属性添加到 django 模型表单中的字段
【发布时间】:2013-10-29 15:51:13
【问题描述】:

我有一个像下面这样的 django 模型

models.py

class Product(models.Model):
    name = models.CharField(max_length = 300)
    description = models.TextField(max_length = 2000)
    created = models.DateTimeField(auto_now_add = True)
    updated = models.DateTimeField(auto_now = True)

    def __unicode__(self):
        return self.name

forms.py

class ProductForm(ModelForm):
    class Meta:
        model = Product
        exclude = ('updated', 'created')

product_form.py(只是一个例子)

 <form enctype="multipart/form-data" action="{% url 'add_a_product' %}" method="post">
         <div id="name">
           {{form.name}}
         </div> 
         <div id="description">
           {{form.description}}
         </div> 
   </form> 

其实我想显示/渲染如下的 html 输出

<input id="common_id_for_inputfields" type="text" placeholder="Name" class="input-calss_name" name="Name">

<input id="common_id_for_inputfields" type="text" placeholder="Description" class="input-calss_name" name="description">

那么最后如何在上述代码中的模型表单字段中添加属性(id、placeholder、class)?

【问题讨论】:

标签: django forms attributes django-forms form-fields


【解决方案1】:

我知道这是一个老问题,但如果有人仍然希望将自定义类添加到他的所有表单字段中,那么您可以使用这一行

class ProductForm(ModelForm):
    class Meta:
        model = Product
        exclude = ('updated', 'created')
def __init__(self, *args, **kwargs):
    super(ProductForm, self).__init__(*args, **kwargs)
    custom_attrs = {
        'class': 'form-control',
        'toggle-data': 'mydiv',
    }
    # adds our custom_attrs to each element of the form 
    [self.fields[i].widget.attrs.update(custom_attrs) for i in self.fields]

【讨论】:

    【解决方案2】:

    我真的很喜欢 Dmitriy Sintsov 的回答,但它不起作用。这是一个有效的版本:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({
                'class': 'form-control'
        })
    

    更新

    添加这个条件更好

    if self.fields[field].widget.__class__.__name__ in ('AdminTextInputWidget' , 'Textarea' , 'NumberInput' , 'AdminURLFieldWidget', 'Select'): 
         self.fields[field].widget.attrs.update({ 'class': 'form-control' })
    

    【讨论】:

    • 这比每次都要形成整个 Widget 要好得多。我创建了一个扩展 forms.ModelForm 的类 BasicForm 来做到这一点。我只是扩展 BasicForm 而不是模型表单,并在所有表单上自动获取引导类。我更进一步,将这些类附加到可能已经存在的任何自定义 css 类中。有关代码示例,请参见我的答案。
    【解决方案3】:

    优秀 mariodev 答案的略微修改版本,将引导类添加到所有表单字段,因此我不必手动为每个字段重新创建表单输入小部件(短 Python 3.x super()):

    class ProductForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            for field in self.fields:
                self.fields[field].widget.attrs.update({
                    'class': 'form-control'
                })
    

    【讨论】:

    • 如果您使用“self.Meta.fields”的“self.fields”,它也可以工作。
    【解决方案4】:

    你可以更新forms.py如下

    class ProductForm(ModelForm):
        class Meta:
            model = Product
            exclude = ('updated', 'created')
            widgets={
                       "name":forms.TextInput(attrs={'placeholder':'Name','name':'Name','id':'common_id_for_imputfields','class':'input-class_name'}),
                       "description":forms.TextInput(attrs={'placeholder':'description','name':'description','id':'common_id_for_imputfields','class':'input-class_name'}),
                    }  
    

    【讨论】:

      【解决方案5】:

      add_class 过滤器用于将 CSS 类添加到表单字段:

       {% load widget_tweaks %}     
          <form enctype="multipart/form-data" action="{% url 'add_a_product' %}" method="post">
                       <div id="name">
                         {{form.name|add_class:"input-calss_name"}}
                       </div> 
                       <div id="description">
                         {{form.description|add_class:"input-calss_name"}}
                       </div> 
                 </form> 
      

      django-widget-tweaks library

      【讨论】:

      • 如果您不想覆盖默认表单,这就是要走的路!多年来,我一直在 Django 项目中使用它。 {% render_field field class+="form-check-input" %}
      【解决方案6】:

      为了回答 Derick Hayes 的问题,我创建了一个扩展 forms.ModelForm 的类 BasicForm,它将引导类添加到扩展它的每个表单中。

      对于我的表单,我只是扩展 BasicForm 而不是模型表单,并自动在所有表单上获取引导类。我更进一步,将这些类附加到任何可能已经存在的自定义 css 类中。

      class BaseModelForm(forms.ModelForm):
      
      def __init__(self, *args, **kwargs):
          super(BaseModelForm, self).__init__(*args, **kwargs)
          # add common css classes to all widgets
          for field in iter(self.fields):
              #get current classes from Meta
              classes = self.fields[field].widget.attrs.get("class")
              if classes is not None:
                  classes += " form-control"
              else:
                  classes = "form-control"
              self.fields[field].widget.attrs.update({
                  'class': classes
              })
      

      【讨论】:

        【解决方案7】:

        您可以执行以下操作:

        class ProductForm(ModelForm):
            name = forms.CharField(label='name ', 
                    widget=forms.TextInput(attrs={'placeholder': 'name '}))
        

        【讨论】:

          【解决方案8】:

          字段 id 应该由 django 自动生成,以覆盖其他字段:

          class ProductForm(ModelForm):
              class Meta:
                  model = Product
                  exclude = ('updated', 'created')
          
              def __init__(self, *args, **kwargs):
                  super(ProductForm, self).__init__(*args, **kwargs)
                  self.fields['name'].widget.attrs\
                      .update({
                          'placeholder': 'Name',
                          'class': 'input-calss_name'
                      })
          

          【讨论】:

          • id 真的应该自动生成吗?您也可以覆盖 id。
          • 您也可以覆盖 id(就像我向您展示的那样,您可以覆盖任何属性),但我认为最好使用 django 生成的 id,除非您无法控制它们(就像您使用 3rd 方 js 库或 smth..)
          【解决方案9】:

          您可以执行以下操作:

          #forms.py
          class ProductForm(ModelForm):
              class Meta:
                  model = Product
                  exclude = ('updated', 'created')
          
              def __init__(self, *args, **kwargs):
                  super(ProductForm, self).__init__(*args, **kwargs)
                  self.fields['description'].widget = TextInput(attrs={
                      'id': 'myCustomId',
                      'class': 'myCustomClass',
                      'name': 'myCustomName',
                      'placeholder': 'myCustomPlaceholder'})
          

          【讨论】:

          • 这对我来说效果很好,除了它从我的 Select 小部件中删除了所有选项。我发现你可以一起跳过小部件声明,仍然像这样设置它的属性:self.fields['description'].widget.attrs={ 'id': 'myCustomId', 'class': 'myCustomClass', 'name': 'myCustomName', 'placeholder': 'myCustomPlaceholder'} 对我来说似乎更干净了。
          • 如果您想将引导类添加到所有表单而不必每次都覆盖构造函数,请参阅下面的答案。
          • 还有没有办法给出和名字一样的id?
          猜你喜欢
          • 2020-11-29
          • 2016-10-04
          • 2017-10-23
          • 1970-01-01
          • 2019-02-03
          • 2018-07-31
          • 2011-09-17
          • 2018-08-07
          • 1970-01-01
          相关资源
          最近更新 更多