【问题标题】:Django: How do I add arbitrary html attributes to input fields on a form?Django:如何将任意 html 属性添加到表单上的输入字段?
【发布时间】:2011-02-23 12:37:29
【问题描述】:

我有一个使用这样的模板呈现的输入字段:

<div class="field">
   {{ form.city }}
</div>

呈现为:

<div class="field">
    <input id="id_city" type="text" name="city" maxlength="100" />
</div>

现在假设我想在渲染的输入元素中添加一个autocomplete="off" 属性,我该怎么做?或onclick="xyz()"class="my-special-css-class"

【问题讨论】:

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


    【解决方案1】:

    Check this page

    city = forms.CharField(widget=forms.TextInput(attrs={'autocomplete':'off'}))
    

    【讨论】:

    • 好的,谢谢。就我而言,我使用的是 ModelForm 所以我没有明确定义表单字段(例如 class AddressForm(forms.ModelForm): class Meta: model = models.Address )这是否意味着我不能使用 ModelForm 或者有什么特别的我需要做什么?
    • @InfinitelyLoopy 在 init for 表单中,您可以添加一些代码来获取字段并修改其小部件属性。这是我之前用来修改 3 个字段的一些: ``` for field_name in ['image', 'image_small', 'image_mobile']: field = self.fields.get(field_name) field.widget.attrs['data-文件'] = '文件' ```
    • 那些不接受像“必需”和“自动对焦”这样的参数的属性呢?
    • 这个解决方案很糟糕,因为没有关注点分离。 HTML 属性不应该用 python 代码 IMO 编写。 Mikhail Korobov 解决方案更胜一筹。
    【解决方案2】:

    抱歉打了广告,但我最近发布了一个应用程序 (https://github.com/kmike/django-widget-tweaks),它使此类任务变得更加轻松,因此设计人员可以在不接触 python 代码的情况下做到这一点:

    {% load widget_tweaks %}
    ...
    <div class="field">
       {{ form.city|attr:"autocomplete:off"|add_class:"my_css_class" }}
    </div>
    

    或者,或者,

    {% load widget_tweaks %}
    ...
    <div class="field">
       {% render_field form.city autocomplete="off" class+="my_css_class" %}
    </div>
    

    【讨论】:

    • 不错的应用 Mike,正是我想要的!
    • 文档没有告诉您在设置中将“widget_tweaks”添加到已安装的应用程序中,可能值得将其放入文档中。
    • 嗨,James,它没有被强调,但在“安装”部分已经有一个关于将“widget_tweaks”添加到 INSTALLED_APPS 的说明。
    • @MikhailKorobov 非常感谢这个应用程序,它帮助了我很多!这正是我正在寻找的正确的东西。我需要一个来自 ModelForm 的表单,并且不想手动将此属性插入每个字段(其中 40 个),所以我优雅地设法在几秒钟内达到相同的结果:) 这应该是公认的答案!
    • 我正打算写这样的应用程序。感谢您节省了我的精力。
    【解决方案3】:

    如果您使用的是“ModelForm”:

    class YourModelForm(forms.ModelForm):
        def __init__(self, *args, **kwargs):
            super(YourModelForm, self).__init__(*args, **kwargs)
            self.fields['city'].widget.attrs.update({
                'autocomplete': 'off'
            })
    

    【讨论】:

    • 好!现在无需显式定义所有小部件。
    【解决方案4】:

    如果您使用ModelForm,除了在他的回答中提供@Artificioo 使用__init__ 的可能性之外,Meta 中有一个widgets 字典:

    class AuthorForm(ModelForm):
        class Meta:
            model = Author
            fields = ('name', 'title', 'birth_date')
            widgets = {
                'name': Textarea(attrs={'cols': 80, 'rows': 20}),
            }
    

    Relevant documentation

    【讨论】:

    • 试图弄清楚为什么这比上面的答案得到的支持更少......有时我认为 Django/Python 开发人员只是更喜欢更难的做事方式......
    • @trpt4him 使用 init 方法对于创建可以在其他表单中重复使用的 Mixin 或基类很有用。这在大中型项目中很典型。 Meta.widgets 非常适合单个表单。所以,两者都是很好的答案。
    【解决方案5】:

    我不想为此使用整个应用程序。 相反,我在这里找到了以下代码https://blog.joeymasip.com/how-to-add-attributes-to-form-widgets-in-django-templates/

    # utils.py
    from django.template import Library
    register = Library()
    
    @register.filter(name='add_attr')
    def add_attr(field, css):
        attrs = {}
        definition = css.split(',')
    
        for d in definition:
            if ':' not in d:
                attrs['class'] = d
            else:
                key, val = d.split(':')
                attrs[key] = val
    
        return field.as_widget(attrs=attrs)
    

    在html文件中使用标签

    {% load utils %}
    {{ form.field_1|add_attr:"class:my_class1 my_class2" }}
    {{ form.field_2|add_attr:"class:my_class1 my_class2,autocomplete:off" }}
    

    【讨论】:

      【解决方案6】:

      我花了好几天时间尝试创建可重用的表单模板,以在 Django 表单中创建和更新模型。请注意,我正在使用 ModelForm 来更改或创建对象。我也在使用引导程序来设置我的表单样式。 过去我对一些表单使用了 django_form_tweaks,但我需要一些自定义,而不需要很多模板依赖。因为我的项目中已经有了 jQuery,所以我决定利用它的属性来设置表单的样式。 这是代码,可以使用任何形式。

      #forms.py
      from django import forms
      from user.models import User, UserProfile
      from .models import Task, Transaction
      
      class AddTransactionForm(forms.ModelForm):
          class Meta:
             model = Transaction
             exclude = ['ref_number',]
             required_css_class = 'required'
      

      Views.py

      @method_decorator(login_required, name='dispatch')
      class TransactionView(View):
      def get(self, *args, **kwargs):
          transactions = Transaction.objects.all()
          form = AddTransactionForm
          template = 'pages/transaction.html'
          context = {
              'active': 'transaction',
              'transactions': transactions,
              'form': form
          }
          return render(self.request, template, context)
      
      def post(self, *args, **kwargs):
          form = AddTransactionForm(self.request.POST or None)
          if form.is_valid():
              form.save()
              messages.success(self.request, 'New Transaction recorded succesfully')
              return redirect('dashboard:transaction')
          messages.error(self.request, 'Fill the form')
          return redirect('dashboard:transaction')
      

      HTML 代码 注意:我正在使用 bootstrap4 模式来消除创建许多视图的麻烦。也许最好使用通用的 CreateView 或 UpdateView。 链接 Bootstrap 和 jqQery

       <div class="modal-body">
          <form method="post" class="md-form" action="." enctype="multipart/form-data">
            {% csrf_token %}
            {% for field in form %}
            <div class="row">
              <div class="col-md-12">
                <div class="form-group row">
                  <label for="" class="col-sm-4 col-form-label {% if field.field.required %}
                  required font-weight-bolder text-danger{%endif %}">{{field.label}}</label>
                  <div class="col-sm-8">
                    {{field}}
                  </div>
      
                </div>
              </div>
            </div>
      
            {% endfor %}
      
            <input type="submit" value="Add Transaction" class="btn btn-primary">
          </form>
        </div>
      

      Javascript代码记得在$(document).ready(function() { /* ... */});函数中加载这个。

      var $list = $("#django_form :input[type='text']");
      $list.each(function () {
          $(this).addClass('form-control')
        });
        var $select = $("#django_form select");
        $select.each(function () {
          $(this).addClass('custom-select w-90')
        });
        var $list = $("#django_form :input[type='number']");
        $list.each(function () {
          $(this).addClass('form-control')
        });
        var $list = $("form :input[type='text']");
        $list.each(function () {
          $(this).addClass('form-control')
        });
        var $select = $("form select");
        $select.each(function () {
          $(this).addClass('custom-select w-90')
        });
        var $list = $("form :input[type='number']");
        $list.each(function () {
          $(this).addClass('form-control')
        });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 2015-01-19
        • 1970-01-01
        • 2018-06-11
        • 1970-01-01
        • 2012-07-13
        相关资源
        最近更新 更多