204

フォームがあるとします

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

レンダリングされたページでクラスに基づいて jQuery を使用できるように、各フィールドに css クラスを定義する方法はありますか?

フォームを手動で作成する必要がないことを望んでいました。

4

14 に答える 14

190

Python コードの変更を必要としないため、デザイナーや 1 回限りのプレゼンテーションの変更に適したさらに別のソリューション: django-widget-tweaks。誰かがそれが役に立つことを願っています。

于 2011-01-13T01:56:34.787 に答える
95

私自身の質問に答えました。はぁ

http://docs.djangoproject.com/en/dev/ref/forms/widgets/#django.forms.Widget.attrs

ウィジェットコンストラクターに渡されたことに気づきませんでした。

于 2008-12-30T18:20:28.533 に答える
82

クラスでフィールドを宣言した後にクラス定義をウィジェットに追加する別のソリューションを次に示します。

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'
于 2008-12-30T18:32:11.100 に答える
47

django-widget-tweaksを使用してください。使いやすく、かなりうまく機能します。

それ以外の場合は、カスタム テンプレート フィルターを使用してこれを行うことができます。

この方法でフォームをレンダリングすることを検討してください:

<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject }}
    </div>
</form>

form.subject はas_widgetメソッドを持つBoundFieldのインスタンスです。

「my_app/templatetags/myfilters.py」でカスタムフィルター「addcss」を作成できます

from django import template

register = template.Library()

@register.filter(name='addcss')
def addcss(value, arg):
    css_classes = value.field.widget.attrs.get('class', '').split(' ')
    if css_classes and arg not in css_classes:
        css_classes = '%s %s' % (css_classes, arg)
    return value.as_widget(attrs={'class': css_classes})

次に、フィルターを適用します。

{% load myfilters %}
<form action="/contact/" method="post">
    {{ form.non_field_errors }}
    <div class="fieldWrapper">
        {{ form.subject.errors }}
        <label for="id_subject">Email subject:</label>
        {{ form.subject|addcss:'MyClass' }}
    </div>
</form>

form.subjects は、「MyClass」css クラスでレンダリングされます。

この助けを願っています。

編集1

  • dimyGの回答に従ってフィルターを更新します

  • django-widget-tweak リンクを追加

編集2

  • Bhydのコメントに従ってフィルターを更新する
于 2013-09-23T14:55:01.993 に答える
33

docs.djangoproject.comでポイントされたメソッドを拡張します。

class MyForm(forms.Form): 
    comment = forms.CharField(
            widget=forms.TextInput(attrs={'size':'40'}))

すべてのフィールドのネイティブウィジェットタイプを知る必要があるのは面倒だと思いました。また、フォームフィールドにクラス名を付けるためだけにデフォルトをオーバーライドするのは面白いと思いました。これは私にとってはうまくいくようです:

class MyForm(forms.Form): 
    #This instantiates the field w/ the default widget
    comment = forms.CharField()

    #We only override the part we care about
    comment.widget.attrs['size'] = '40'

これは私には少しきれいに思えます。

于 2010-11-25T00:06:15.370 に答える
33

フォーム内のすべてのフィールドに特定のクラスを継承させたい場合は、 から継承する親クラスを定義し、forms.ModelFormそれから継承するだけです。

class BaseForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BaseForm, self).__init__(*args, **kwargs)
        for field_name, field in self.fields.items():
            field.widget.attrs['class'] = 'someClass'


class WhateverForm(BaseForm):
    class Meta:
        model = SomeModel

これにより'form-control'、コードの複製を追加することなく、アプリケーションのすべてのフォームのすべてのフィールドにクラスを自動的に追加することができました。

于 2013-12-13T18:35:43.863 に答える
17

ビューを変更する簡単な方法を次に示します。テンプレートに渡す直前にビューに以下を追加します。

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}
于 2011-01-12T10:42:45.900 に答える
5

これは、すべてのフィールドに同じクラスを与える上記のバリエーションです (例: jquery nice rounded corner)。

  # Simple way to assign css class to every field
  def __init__(self, *args, **kwargs):
    super(TranslatedPageForm, self).__init__(*args, **kwargs)
    for myField in self.fields:
      self.fields[myField].widget.attrs['class'] = 'ui-state-default ui-corner-all'
于 2010-03-04T07:38:15.777 に答える
2

ビューをオーバーライドせずにサードパーティのアプリを変更する場合など、(view.py または form.py ではなく)テンプレートのフォームのフィールドにクラスを追加する場合は、説明されているテンプレート フィルターを使用します。 Charlesthk回答は非常に便利です。ただし、この回答では、テンプレート フィルターは、フィールドに含まれる可能性のある既存のクラスをオーバーライドします。

これを編集として追加しようとしましたが、新しい回答として書くことが提案されました。

したがって、フィールドの既存のクラスを尊重するテンプレート タグは次のとおりです。

from django import template

register = template.Library()


@register.filter(name='addclass')
def addclass(field, given_class):
    existing_classes = field.field.widget.attrs.get('class', None)
    if existing_classes:
        if existing_classes.find(given_class) == -1:
            # if the given class doesn't exist in the existing classes
            classes = existing_classes + ' ' + given_class
        else:
            classes = existing_classes
    else:
        classes = given_class
    return field.as_widget(attrs={"class": classes})
于 2016-12-13T19:37:15.637 に答える
1

Django Crispy Formsを使用することもできます。これは、Bootstrap や Foundation などの CSS フレームワークを使用する場合にフォームを定義するための優れたツールです。また、フォーム フィールドのクラスを簡単に指定できます。

フォーム クラスは次のようになります。

from django import forms

from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Div, Submit, Field
from crispy_forms.bootstrap import FormActions

class SampleClass(forms.Form):
    name = forms.CharField(max_length=30)
    age = forms.IntegerField()
    django_hacker = forms.BooleanField(required=False)

    helper = FormHelper()
    helper.form_class = 'your-form-class'
    helper.layout = Layout(
        Field('name', css_class='name-class'),
        Field('age', css_class='age-class'),
        Field('django_hacker', css-class='hacker-class'),
        FormActions(
            Submit('save_changes', 'Save changes'),
        )
    )
于 2016-12-21T17:09:26.637 に答える
1

フォームコンストラクター( init関数)で、またはフォームクラスが開始された後にこれを行うことができることがわかりました。これは、独自のフォームを作成しておらず、そのフォームが別の場所から来ている場合に必要になることがあります -

def some_view(request):
    add_css_to_fields = ['list','of','fields']
    if request.method == 'POST':
        form = SomeForm(request.POST)
        if form.is_valid():
            return HttpResponseRedirect('/thanks/')
    else:
        form = SomeForm()

    for key in form.fields.keys():
        if key in add_css_to_fields:
            field = form.fields[key]
            css_addition = 'css_addition '
            css = field.widget.attrs.get('class', '')
            field.widget.attrs['class'] = css_addition + css_classes

    return render(request, 'template_name.html', {'form': form})
于 2015-03-05T09:44:53.053 に答える