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"

回答:


126

このページをチェック

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

2
ありがとうございます。私の場合、私はModelFormを使用しているため、フォームフィールドを明示的に定義していません(例:クラスAddressForm(forms.ModelForm):クラスMeta:model = models.Address)これは、ModelFormを使用できないことを意味しますか、それとも特別なものがありますか?する必要があります?
ユーザー


1
@InfinitelyLoopy for init for form 内に、フィールドを取得してウィジェットの属性を変更するコードを追加できます。以下は、3つのフィールドを変更するために以前に使用したものです: `` `for field_name in ['image'、 'image_small'、 'image_mobile']:field = self.fields.get(field_name)field.widget.attrs ['data- file '] =' file '`` `
Stuart Axon

4
「必須」や「オートフォーカス」などの引数をとらない属性についてはどうですか?
Wilhelm Klopp、2015年

1
懸念の分離がないため、このソリューションは不適切です。HTML属性はPythonコードIMOで記述しないでください。ミハイル・コロボフのソリューションは優れています。
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、

こんにちはジェームス、強調されていませんが、「インストール」セクションには、INSTALLED_APPSに「widget_tweaks」を追加することに関する注記がすでにあります。
ミハイルコロボフ2011年

@MikhailKorobovこのアプリを本当にありがとう、それは私をたくさん助けてくれました!これはまさに私が探していたものでした。ModelFormのフォームが必要で、すべてのフィールド(40個)にこの属性を手動で挿入したくなかったので、エレガントに数秒で同じ結果を達成できました:)これは受け入れられる答えです!
Ljubisa Livac 2016年

そのようなアプリケーションを書くつもりでした。努力を節約してくれてありがとう。
Anuj TBE 2017

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öf2016

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

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を使用する方が良いでしょう。リンクブートストラップと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')
  });
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.