質問

フォームがあるとします

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

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

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

役に立ちましたか?

解決 2

自分の質問に答えました。 ため息

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

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

他のヒント

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

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

def __init__(self, *args, **kwargs):
    super(SampleClass, self).__init__(*args, **kwargs)
    self.fields['name'].widget.attrs['class'] = 'my_class'

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は BoundField <のインスタンスです/ a> as_widget メソッドがあります。

カスタムフィルター&quot; addcss&quot;を作成できます。 &quot; my_app / templatetags / myfilters.py&quot;

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は&quot; MyClass&quot;でレンダリングされますcssクラス。

このヘルプをお待ちしています。

編集1

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

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

編集2

  • Bhyd のコメントに従ってフィルターを更新

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'

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

フォームのすべてのフィールドに特定のクラスを継承させる場合は、 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' クラスを自動的に追加できました。

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

form = MyForm(instance = instance.obj)
form.fields['email'].widget.attrs = {'class':'here_class_name'}

次のようにフォームにクラスを追加するだけです。

class UserLoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(
        attrs={
        'class':'form-control',
        'placeholder':'Username'
        }
    ))
    password = forms.CharField(widget=forms.PasswordInput(
        attrs={
        'class':'form-control',
        'placeholder':'Password'
        }
    ))

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

  # 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'

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

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

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

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})

これを試すことができます。

class SampleClass(forms.Form):
  name = forms.CharField(max_length=30)
  name.widget.attrs.update({'class': 'your-class'})
...

詳細は、 Djangoウィジェット

結果として、フォームコンストラクター( 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})

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'),
        )
    )
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top