장고 양식의 CSS 스타일링


150

다음 스타일을 지정하고 싶습니다.

forms.py :

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

contact_form.html :

<form action="" method="post">
  <table>
    {{ form.as_table }}
  </table>
  <input type="submit" value="Submit">
</form>

예를 들어, 어떻게 내가 설정하는 클래스 또는 ID가 을 위해 subject, email, message에 외부 스타일 시트를 제공하기 위해?

답변:


192

: 내 대답에서 촬영 <DIV 클래스 = 'field_type'> 장고와 양식 필드를 마크 업하는 방법

class MyForm(forms.Form):
    myfield = forms.CharField(widget=forms.TextInput(attrs={'class' : 'myfieldclass'}))

또는

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel

    def __init__(self, *args, **kwargs):
        super(MyForm, self).__init__(*args, **kwargs)
        self.fields['myfield'].widget.attrs.update({'class' : 'myfieldclass'})

또는

class MyForm(forms.ModelForm):
    class Meta:
        model = MyModel
        widgets = {
            'myfield': forms.TextInput(attrs={'class': 'myfieldclass'}),
        }

--- 편집 ---
위의 내용은 질문을 수행하는 원래 질문의 코드를 변경하는 가장 쉬운 방법입니다. 또한 다른 장소에서 양식을 재사용 할 경우 자신을 반복하지 못하게합니다. Django의 as_table / as_ul / as_p 양식 메소드를 사용하는 경우 클래스 또는 기타 속성이 작동합니다. 완전히 커스텀 렌더링을 위해 모든 권한이 필요한 경우, 명확하게 문서화됩니다

-편집 2 ---
ModelForm에 위젯과 속성을 지정하는 새로운 방법을 추가했습니다.


27
프리젠 테이션을 비즈니스 로직과 혼합하는 것은 권장되지 않습니다.
Torsten Engelbrecht

8
이 프레젠테이션은 어떻습니까? 요소에 식별자 또는 분류 인 클래스를 제공합니다. 여전히 다른 곳에서 무엇을하는지 정의해야합니다
shadfc

9
예, 아니오 첫 번째 CSS 클래스는 사용하기에 더 좋은 고유 식별자가 필요한 경우 스타일링에 사용되는 규칙에 따릅니다 id. 둘째, 일반적으로 템플릿 측의 책임을 져야합니다. 특히 프론트 엔드 메소드 (js, css)를 통해이 클래스에 액세스하려는 경우 특히 그렇습니다. 나는 당신의 대답이 틀렸다고 말하지 않았습니다. 제 생각에 그것은 단지 나쁜 습관입니다 (특히 프론트 엔드 및 백엔드 개발자와 팀에서 일할 때).
Torsten Engelbrecht

6
이 코드가 필요한 클래스를 추가하기 만하면 어리석게 보입니다. 이러한 영역 (특히 CSS가 많은 사이트의 경우)에서 HTML / CSS를 하드 코딩하는 것이 더 쉬운 것 같습니다.
David542

9
장고가 너무 어색합니다!
브라이스

103

이 작업은 사용자 정의 템플릿 필터를 사용하여 수행 할 수 있습니다. 이 방법으로 양식을 렌더링하십시오.

<form action="/contact/" method="post">
  {{ form.non_field_errors }}
  <div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject }}
    <span class="helptext">{{ form.subject.help_text }}</span>
  </div>
</form>

form.subject의 인스턴스 BoundField갖는 as_widget()방법.

my_app / templatetags / myfilters.pyaddclass 에서 사용자 정의 필터 를 만들 수 있습니다 .

from django import template

register = template.Library()

@register.filter(name='addclass')
def addclass(value, arg):
    return value.as_widget(attrs={'class': arg})

그런 다음 필터를 적용하십시오.

{% load myfilters %}

<form action="/contact/" method="post">
  {{ form.non_field_errors }}
  <div class="fieldWrapper">
    {{ form.subject.errors }}
    {{ form.subject.label_tag }}
    {{ form.subject|addclass:'MyClass' }}
    <span class="helptext">{{ form.subject.help_text }}</span>
  </div>
</form>

form.subjects그런 다음 MyClassCSS 클래스 로 렌더링됩니다 .


5
이것은보다 깨끗하고 구현하기 쉬운 솔루션 중 하나입니다.
사용자

5
이 답변은 최고 답변이어야합니다! Django가 제안한 솔루션보다 정말 깨끗합니다! @Charlesthk
David D.

4
정말 도움이되었습니다. 처음에는 나에게 분명하지 않았지만이 클래스를 사용하여 여러 클래스를 추가 할 수도 있습니다.{{ form.subject|addclass:'myclass1 myclass2' }}
smg

나는 이것이 HTML 클래스를 HTML 파일에 유지할 수 있다는 것을 좋아한다. 스타일링 작업시 모델 및 / 또는 양식이 아닌 스타일 시트와 구조간에 앞뒤로 이동합니다.
Kevin

29

추가하지 않으려면 어떤 (shadfc의 대답 @에 코멘트에서 언급 한 바와 같이) 폼에 코드를, 그것은 확실히 가능하며, 여기에 두 가지 옵션이 있습니다.

먼저 한 번에 전체 양식이 아닌 HTML에서 개별적 으로 필드를 참조하면됩니다 .

<form action="" method="post">
    <ul class="contactList">
        <li id="subject" class="contact">{{ form.subject }}</li>
        <li id="email" class="contact">{{ form.email }}</li>
        <li id="message" class="contact">{{ form.message }}</li>
    </ul>
    <input type="submit" value="Submit">
</form>

(또한 정렬되지 않은 목록으로 변경했습니다 .)

둘째, HTML , Django 로 양식출력 하는 문서에서 참고하십시오 .

필드 ID는 필드 이름 앞에 'id_'를 추가하여 생성됩니다. id 속성 및 태그는 기본적으로 출력에 포함됩니다.

모든 양식 필드에는 이미 고유 한 ID가 있습니다. 따라서 CSS 파일에서 id_subject 를 참조 하여 주제 필드의 스타일을 지정하십시오 . 난 당신이 걸릴 때이 방법 양식 동작합니다입니다,주의해야 기본 단지 형태가 아닌 개별 필드를 인쇄 할 필요 HTML을 :

<ul class="contactList">
    {{ form }}  # Will auto-generate HTML with id_subject, id_email, email_message 
    {{ form.as_ul }} # might also work, haven't tested
</ul>

양식을 출력 할 때 다른 옵션에 대해서는 이전 링크를 참조하십시오 (테이블 등을 수행 할 수 있음).

참고-이것은 각 요소에 클래스 를 추가하는 것과 같지 않다는 것을 알고 있습니다 (양식에 필드를 추가 한 경우 CSS도 업데이트해야 함) -id로 모든 필드를 쉽게 참조 할 수 있습니다. CSS에서 다음과 같이 :

#id_subject, #id_email, #email_message 
{color: red;}

두 번째 해결책을 시도했지만 작동하지 않았습니다. id_email에 대한 클래스를 만들었고 결과를 얻지 못했습니다.
거의 초보자

@almostabeginner 디버깅에 제안 할 수있는 한 가지-브라우저에서 페이지를 본 후에는 일반적으로 마우스 오른쪽 버튼으로 클릭하여 페이지 소스보기를 사용 하고 Django가 생성하는 실제 전체 페이지를보십시오. ID 또는 클래스 식별자가 예상 되는 필드가 있는지 확인하십시오 . 또한 대부분의 브라우저는 (플러그인을 설치하여) 페이지에 적용된 CSS 를 보여주는 디버거를 실행할 수 있으며 진행 상황을 확인하는 데 도움이됩니다.
John C

@almostabeginner도 약간의 샘플 코드를 추가했습니다. 텍스트만으로는 명확하지 않은 경우-개별 필드가 아닌 양식 자체를 참조해야하며, 이때 양식에 설명 된대로 id 가 포함 된 HTML이 자동 생성 됩니다. 잘하면 그것은 도움이됩니다.
John C

1
도움에 감사드립니다. 문제는 전혀 CSS가 아니 었습니다. 문제는 캐시와 관련이 있습니다. 따라서 내 오래된 CSS가 저장되었으므로 변경 내용이 표시되지 않습니다. 크롬에서 캐시를 지우고 모든 업데이트가 표시되기 시작했습니다.
거의 초보자

15

블로그 게시물, 사용자 정의 템플릿 필터를 사용하여 필드에 CSS 클래스를 추가 할 수 있습니다.

from django import template
register = template.Library()

@register.filter(name='addcss')
def addcss(field, css):
    return field.as_widget(attrs={"class":css})

이것을 앱의 templatetags / 폴더에 넣으면 이제 할 수 있습니다

{{field|addcss:"form-control"}}

2
이것은이 게시물에 대한 실제 답변으로 받아 들여 져야합니다 :)
mvdb

지금까지 최고의 솔루션.
Mods Vs Rockers

1
훌륭합니다, 고마워요! 실제로 태그를로드하는 것을 잊지 마십시오. 또한, 장고 2.1 유일한 방법은 내가 장고 템플릿은 settings.py에서 옵션을 추가했다 찾기 위해 얻을 수있는 '라이브러리'{ 'add_css': 'app.templatetags.tag_name',}
simonbogarde

11

당신은 이렇게 할 수 있습니다 :

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    subject.widget.attrs.update({'id' : 'your_id'})

그것이 효과가 있기를 바랍니다.

이그나 스


고마워요 정확한 답변!
Rudresh Ajgaonkar

9

이 라이브러리를 사용할 수 있습니다 : https://pypi.python.org/pypi/django-widget-tweaks

다음을 수행 할 수 있습니다.

{% load widget_tweaks %}
<!-- add 2 extra css classes to field element -->
{{ form.title|add_class:"css_class_1 css_class_2" }}

1
Charlesthk 솔루션을 살펴보십시오. 추가 라이브러리를 추가하지 않고도 동일합니다
.

@DavidW .: 예. 그러나 Widget Tweaks에는와 같은 더 많은 필터가 render_field있습니다.
mrdaliri

5

넌 할 수있어:

<form action="" method="post">
    <table>
        {% for field in form %}
        <tr><td>{{field}}</td></tr>
        {% endfor %}
    </table>
    <input type="submit" value="Submit">
</form>

그런 다음 <td>태그 와 같은 클래스 / ID를 추가 할 수 있습니다 . 물론 원하는 다른 태그를 사용할 수 있습니다. 확인 장고 형태의 작업을 각각 사용할 것을 예로 field(형태 {{field}}, 예를 들어 바로 입력 태그가 아닌 라벨 등을 출력한다).


3

한 가지 해결책은 페이지가 준비된 후 JavaScript를 사용하여 필요한 CSS 클래스를 추가하는 것입니다. 예를 들어, 부트 스트랩 클래스를 사용하여 스타일링 장고 양식 출력 (간단하게 사용되는 jQuery) :

<script type="text/javascript">
    $(document).ready(function() {
        $('#some_django_form_id').find("input[type='text'], select, textarea").each(function(index, element) {
            $(element).addClass("form-control");
        });
    });
</script>

이렇게하면 스타일 지정을 비즈니스 로직과 혼합하는 것이 어려워집니다.


3

다음과 같이 양식을 작성하십시오.

    class MyForm(forms.Form):
         name = forms.CharField(widget=forms.TextInput(attr={'class':'name'}),label="Your Name")
         message = forms.CharField(widget=forms.Textarea(attr={'class':'message'}), label="Your Message")

HTML 필드에서 다음과 같은 작업을 수행하십시오.

{% for field in form %}
      <div class="row">
        <label for="{{ field.name}}">{{ field.label}}</label>{{ field }}
     </div>
{% endfor %}

그런 다음 CSS에서 다음과 같이 작성하십시오.

.name{
      /* you already have this class so create it's style form here */
}
.message{
      /* you already have this class so create it's style form here */
}
label[for='message']{
      /* style for label */
}

이 답변이 시도해 볼만한 가치가 있기를 바랍니다. 양식이 포함 된 HTML 파일을 렌더링하려면보기를 작성해야합니다.


감사. 하지만 특정 레이블 텍스트를 작성하려면 어떻게해야합니까?
gakeko betsi

2

__init__Django는 HTML에서 속성을 설정 name하고 id속성을 지정 하므로 양식 클래스를 재정의하지 않아도됩니다 input. 다음과 같은 CSS를 가질 수 있습니다.

form input[name='subject'] {
    font-size: xx-large;
}

1
이것에 추가하십시오. "subject = forms ..."가 주어지면 id = "id_subject"및 name = "subject"는 이러한 속성에 대한 Django 규칙입니다. 그러므로 당신은 #id_subject {...}을 할 수 있어야합니다
solartic

@solartic : 당신이 옳아 요, 감사합니다. idDjango가 formets를 위해 만든 필드가 꽤 무서워 지기 때문에 이것을 언급하지 않았습니다 …
tehfink

2

이거 진짜 보이지 않았어 ...

https://docs.djangoproject.com/en/1.8/ref/forms/api/#more-granular-output

더 세분화 된 출력

as_p (), as_ul () 및 as_table () 메소드는 게으른 개발자를위한 지름길입니다. 양식 객체를 표시 할 수있는 유일한 방법은 아닙니다.

class BoundField Form 인스턴스의 단일 필드의 HTML 또는 액세스 속성을 표시하는데 사용됩니다.

이 객체 의 str () ( Python 2의 유니 코드 ) 메소드는이 필드의 HTML을 표시합니다.

단일 BoundField를 검색하려면 필드 이름을 키로 사용하여 양식에서 사전 조회 구문을 사용하십시오.

>>> form = ContactForm()
>>> print(form['subject'])
<input id="id_subject" type="text" name="subject" maxlength="100" />

모든 BoundField 객체를 검색하려면 다음 형식을 반복하십시오.

>>> form = ContactForm()
>>> for boundfield in form: print(boundfield)
<input id="id_subject" type="text" name="subject" maxlength="100" />
<input type="text" name="message" id="id_message" />
<input type="email" name="sender" id="id_sender" />
<input type="checkbox" name="cc_myself" id="id_cc_myself" />

필드 별 출력은 양식 객체의 auto_id 설정을 따릅니다.

>>> f = ContactForm(auto_id=False)
>>> print(f['message'])
<input type="text" name="message" />
>>> f = ContactForm(auto_id='id_%s')
>>> print(f['message'])
<input type="text" name="message" id="id_message" />

2

스타일링에 사용하는 Django 용으로 제작 된 매우 쉬운 도구가 있으며 Bootstrap, Materialize, Foundation 등과 같은 모든 프론트 엔드 프레임 워크에 사용할 수 있습니다. 위젯 조정 문서 : 위젯 비틀기

  1. Django의 일반 뷰와 함께 사용할 수 있습니다
  2. 또는 자신의 형태로 :

장고 가져 오기 양식에서

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=100)
    email = forms.EmailField(required=False)
    message = forms.CharField(widget=forms.Textarea)

기본값을 사용하는 대신 :

{{ form.as_p }} or {{ form.as_ul }}

다음 예제와 같이 HTML과 유사한 스타일을 지정하는 render_field 속성을 사용하여 원하는 방식으로 편집 할 수 있습니다.

template.html

{% load widget_tweaks %}

<div class="container">
   <div class="col-md-4">
      {% render_field form.subject class+="form-control myCSSclass" placeholder="Enter your subject here" %}
   </div>
   <div class="col-md-4">
      {% render_field form.email type="email" class+="myCSSclassX myCSSclass2" %}
   </div>
   <div class="col-md-4">
      {% render_field form.message class+="myCSSclass" rows="4" cols="6" placeholder=form.message.label %}
   </div>
</div>

이 라이브러리는 백엔드에서 유인 프론트 엔드를 잘 분리 할 수있는 기회를 제공합니다.


1

Django 1.10 (아마도 초기에)에서 다음과 같이 할 수 있습니다.

모델:

class Todo(models.Model):
    todo_name = models.CharField(max_length=200)
    todo_description = models.CharField(max_length=200, default="")
    todo_created = models.DateTimeField('date created')
    todo_completed = models.BooleanField(default=False)

    def __str__(self):
        return self.todo_name

형태:

class TodoUpdateForm(forms.ModelForm):
    class Meta:
        model = Todo
        exclude = ('todo_created','todo_completed')

주형:

<form action="" method="post">{% csrf_token %}
    {{ form.non_field_errors }}
<div class="fieldWrapper">
    {{ form.todo_name.errors }}
    <label for="{{ form.name.id_for_label }}">Name:</label>
    {{ form.todo_name }}
</div>
<div class="fieldWrapper">
    {{ form.todo_description.errors }}
    <label for="{{ form.todo_description.id_for_label }}">Description</label>
    {{ form.todo_description }}
</div>
    <input type="submit" value="Update" />
</form>

0

편집 : 내가 제안하는 것을하는 또 다른 (약간 더 나은) 방법은 여기에 대답합니다 : Django form input field styling

위의 모든 옵션은 훌륭합니다. 다른 것이기 때문에이 옵션을 던질 것이라고 생각했습니다.

양식에 사용자 정의 스타일, 클래스 등을 원하는 경우 양식 필드와 일치하는 템플리트에서 html 입력을 작성할 수 있습니다. 예를 들어 CharField의 경우 (기본 위젯은 TextInput) 부트 스트랩 모양의 텍스트 입력을 원한다고 가정하겠습니다. 당신은 이런 식으로 할 것입니다 :

<input type="text" class="form-control" name="form_field_name_here">

그리고만큼 당신이 넣어 양식 필드 이름은 HTML의 일치 name, attribue을 (그리고 위젯 아마뿐만 아니라 입력 유형과 일치해야 함)을 실행할 때 장고 해당 필드에 모두 같은 유효성 검사기를 실행 validate또는 form.is_valid()

레이블, 오류 메시지 및 도움말 텍스트와 같은 다른 form.field.error.as_text스타일의 스타일은 원하는대로 스타일을 지정할 수 있으므로 많은 해결 방법이 필요하지 않습니다 . 실제 필드는 약간의 조정이 필요한 필드입니다.

이것이 최선의 방법인지 또는 내가 권장하는 방법인지는 모르겠지만 방법이며 누군가에게 옳을 수도 있습니다.

다음은 스타일링 양식에 대한 유용한 연습입니다. 여기에는 위젯에 위젯을 사용하거나 위젯을 조정하는 것과 같이 SO에 나열된 대부분의 답변이 포함되어 있습니다. https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html


0

스타일링 위젯 인스턴스

하나의 위젯 인스턴스를 다른 위젯 인스턴스와 다르게 보이게하려면 위젯 오브젝트가 인스턴스화되어 양식 필드에 지정 될 때 (및 CSS 파일에 규칙을 추가 할 때) 추가 속성을 지정해야합니다.

https://docs.djangoproject.com/en/2.2/ref/forms/widgets/

이를 수행하려면 위젯을 작성할 때 Widget.attrs 인수를 사용하십시오.

class CommentForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
    url = forms.URLField()
    comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

양식 정의에서 위젯을 수정할 수도 있습니다.

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField()

    name.widget.attrs.update({'class': 'special'})
    comment.widget.attrs.update(size='40')

또는 필드가 양식에서 직접 선언되지 않은 경우 (예 : 모델 양식 필드) Form.fields 속성을 사용할 수 있습니다.

class CommentForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'special'})
        self.fields['comment'].widget.attrs.update(size='40')

그러면 Django는 렌더링 된 출력에 추가 속성을 포함시킵니다.

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special" required></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40" required></td></tr>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.