development

Django 양식의 CSS 스타일링

big-blog 2020. 7. 1. 07:32
반응형

Django 양식의 CSS 스타일링


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

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에 외부 스타일 시트를 제공하기 위해?


: 내 대답에서 촬영 <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에 위젯과 속성을 지정하는 새로운 방법을 추가했습니다.


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

<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 클래스 로 렌더링됩니다 .


추가하지 않으려면 어떤 (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;}

블로그 게시물, 사용자 정의 템플릿 필터를 사용하여 필드에 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"}}

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

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

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

이그나 스


이 라이브러리를 사용할 수 있습니다 : 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" }}

넌 할 수있어:

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

그런 다음 <td>태그 와 같은 클래스 / ID를 추가 할 수 있습니다 . 물론 원하는 다른 태그를 사용할 수 있습니다. Django 양식 작업을 예로 들어 각 field양식에서 사용 가능한 항목을 확인하십시오 ( {{field}}예 : 레이블이 아닌 입력 태그를 출력하는 등).


이거 진짜 못 봤어 ...

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

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

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

한 가지 해결책은 페이지가 준비된 후 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>

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


There is a very easy to install and great tool made for Django that I use for styling and it can be used for every frontend framework like Bootstrap, Materialize, Foundation, etc. It is called widget-tweaks Documentation: Widget Tweaks

  1. You can use it with Django's generic views
  2. Or with your own forms:

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)

Instead of using default:

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

You can edit it your own way using the render_field attribute that gives you a more html-like way of styling it like this example:

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>

This library gives you the opportunity to have well separated yout front end from your backend


In Django 1.10 (possibly earlier as well) you can do it as follows.

Model:

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

Form:

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

Template:

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

Edit: Another (slightly better) way of doing what I'm suggesting is answered here: Django form input field styling

All the above options are awesome, just thought I'd throw in this one because it's different.

If you want custom styling, classes, etc. on your forms, you can make an html input in your template that matches your form field. For a CharField, for example, (default widget is TextInput), let's say you want a bootstrap-looking text input. You would do something like this:

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

And as long as you put the form field name matches the html name attribue, (and the widget probably needs to match the input type as well) Django will run all the same validators on that field when you run validate or form.is_valid() and

Styling other things like labels, error messages, and help text don't require much workaround because you can do something like form.field.error.as_text and style them however you want. The actual fields are the ones that require some fiddling.

I don't know if this is the best way, or the way I would recommend, but it is a way, and it might be right for someone.

Here's a useful walkthrough of styling forms and it includes most of the answers listed on SO (like using the attr on the widgets and widget tweaks). https://simpleisbetterthancomplex.com/article/2017/08/19/how-to-render-django-form-manually.html


Styling widget instances

If you want to make one widget instance look different from another, you will need to specify additional attributes at the time when the widget object is instantiated and assigned to a form field (and perhaps add some rules to your CSS files).

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

To do this, you use the Widget.attrs argument when creating the widget:

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

You can also modify a widget in the form definition:

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

Or if the field isn’t declared directly on the form (such as model form fields), you can use the Form.fields attribute:

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 will then include the extra attributes in the rendered output:

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

Write your form like:

    class MyForm(forms.Form):
         name = forms.CharField(widget=forms.TextInput(attr={'class':'name'}))
         message = forms.CharField(widget=forms.Textarea(attr={'class':'message'}))

In your HTML field do something like:

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

Then in your CSS write something like:

.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 */
}

Hope this answer is worth a try! Note you must have written your views to render the HTML file that contains the form.

참고URL : https://stackoverflow.com/questions/5827590/css-styling-in-django-forms

반응형