Django:如何在表单的输入字段中添加任意html属性?


101

我有一个用模板渲染的输入字段,如下所示:

<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"

Answers:


126

检查此页

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

2
好的谢谢。就我而言,我正在使用ModelForm,所以我没有明确定义表单字段(例如,类AddressForm(forms.ModelForm):class Meta:model = models.Address),这是否意味着我不能使用ModelForm或有什么特别的东西吗?需要做?
用户2010年


1
在表单的init内的@InfinitelyLoopy中,您可以添加一些代码来获取字段并修改其小部件属性。这是我之前使用的一些字段,用于修改3个字段:“”用于['image','image_small','image_mobile']中的field_name:field = self.fields.get(field_name)field.widget.attrs ['data-文件'] = '文件'```
司徒轴突

4
那些不接受“ required”和“ autofocus”等参数的属性呢?
威廉·克洛普

1
该解决方案很糟糕,因为没有关注点分离。HTML属性不应以python代码IMO编写。Mikhail Korobov解决方案更为出色。
David D.

115

抱歉广告,但我最近发布了一个应用程序(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>

3
不错的应用程序Mike,正是我想要的!
jmagnusson 2011年

该文档没有告诉您在设置中将“ widget_tweaks”添加到已安装的应用中,可能值得将其添加到文档中。
James Lin

詹姆斯,您好,这并没有什么问题,但是在“安装”部分中已经有关于将widget_tweaks添加到INSTALLED_APPS的说明。
米哈伊尔·科罗波夫

@MikhailKorobov非常感谢您使用此应用程序,它对我有很大帮助!这正是我一直在寻找的正确的东西。我需要来自ModelForm的表单,并且不想手动将此属性插入到每个字段(其中有40个),所以我优雅地设法在几秒钟内实现了相同的结果:)这应该是公认的答案!
Ljubisa Livac '16

我打算编写这样的应用程序。多亏了我的努力。
Anuj TBE

31

如果使用“ ModelForm”:

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

3
好!现在无需显式定义所有小部件。
MikaelLindlöf'02

20

如果您正在使用ModelForm,除了可以__init__在他的答案中使用@Artificioo之外,还可以widgets在Meta中使用针对此问题的字典:

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

相关文件


1
试图弄清楚为什么它的投票比上面的答案少...有时我认为Django / Python开发人员只喜欢更难的做事方式
trpt4him

@ trpt4him使用init方法可用于创建可在其他窗体中重用的Mixin或基类。这在中型到大型项目中是典型的。Meta.widgets非常适合单个表单。因此,两者都是很好的答案。
Akhorus 2015年

2

我不想为此使用整个应用程序。相反,我在这里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" }}

0

最终形式的外观和渲染我花了很多天的时间来尝试创建可重用的表单模板,以在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')
  });
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.