2011-04-29 60 views
93

如何樣式如下: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以提供外部樣式表?謝謝

回答

128

從我的回答採取: How to markup form fields with <div class='field_type'> in Django

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

---編輯---
以上是最簡單的改變,使原來的q uestion的代碼完成了所要求的內容。如果您在其他地方重複使用該表格,它也會讓您無法重複自己;如果你使用Django的as_table/as_ul/as_p表單方法,你的類或其他屬性就可以工作。如果您需要完全控制了完全自定義的渲染,這是clearly documented

- EDIT 2 ---
添加到指定窗口小部件和ATTRS了的ModelForm一個新的途徑。

+16

儘管不建議將表示與業務邏輯混合使用。 – 2011-04-29 04:08:54

+4

這個演示文稿如何?你給元素一個類,這只是一個標識符或分類。你仍然必須定義在別處做了什麼 – shadfc 2011-04-29 13:17:52

+6

是和不是。第一個CSS類通常用於樣式,如果你需要一個唯一的標識符,最好使用'id'。其次,它通常是模板方面的責任,可以做到這一點,尤其是如果你要通過前端方法(js,css)來訪問這個類。我沒有說你的答案是錯的。在我看來,這只是一個糟糕的做法(尤其是當你在一個擁有前端和後端開發人員的團隊中工作時)。 – 2011-04-30 03:12:38

9

你可以這樣做:

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

希望工程。

Ignas

+0

謝謝ignas。精確的答案! – 2016-06-28 20:49:15

4

你可以這樣做:

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

然後你就可以添加類/ ID對例如<td>標籤。你當然可以使用任何你想要的其他標籤。以Working with Django forms爲例,表格中每個field可用的內容(例如{{field}}僅輸出輸入標籤,而不是標籤等)。

2

您可能不需要重寫你的窗體類__init__,因爲Django的設置在HTML input小號name & id屬性。你可以有CSS這樣的:

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

要添加到此。鑑於「subject = forms ...」,id =「id_subject」和name =「subject」是這些屬性的Django慣例。因此,你應該也可以做#id_subject {...} – solartic 2011-04-29 04:12:28

+0

@solartic:你說得對,謝謝。我沒有提到這個,因爲Django爲formset創建的'id'字段變得非常多毛... – tehfink 2011-04-29 19:14:12

+0

對我而言沒有效果。 – 2016-12-19 09:56:52

22

如果你不希望添加任何代碼(如在評論中提到@ 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> 

(請注意,我也把它改成一個無序列表

其次,注意在上outputting forms as HTML的文檔,則Django:

字段ID中,生成b y 預先將'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;} 
+0

我試過你的第二個解決方案,但沒有奏效。我爲id_email創建了類,但未能產生任何結果。 – 2016-12-19 09:51:32

+0

@almostabeginner我可以爲調試提出一個建議 - 一旦您在瀏覽器中看到該頁面,請使用_View Page Source_(通常通過右鍵單擊),然後查看Django生成的實際完整頁面。用你期望的_id_或_class_標識符查看這些字段是否存在。另外,大多數瀏覽器(可能通過安裝插件)可以運行一個調試器,向您顯示應用於頁面的_css_,這也有助於瞭解發生了什麼。 – 2016-12-19 18:08:52

+0

@almostabeginner還注意到,我添加了一些示例代碼。如果僅從文本中不清楚 - 您必須引用表單本身,而不是單個字段,此時表單將自動生成包含_ids_的HTML,如上所述。希望有幫助。 – 2016-12-20 14:50:06

6

你可以使用這個庫: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解決方案,它是一樣的,不需要增加一個額外的庫:) – 2014-05-27 13:03:33

+0

@DavidW .:是的,但Widget Tweaks有很多更多的過濾器,比如'render_field'。 – mrdaliri 2014-10-19 05:09:44

70

這可以使用自定義模板過濾器來完成。 考慮你呈現你的表格是這樣的:

<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.py」 自定義過濾器 「addclass」

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將被渲染與「MyClass」css類。

希望得到這個幫助。

+3

這是一個更清潔和易於實施的解決方案 – Medorator 2014-02-06 18:54:46

+4

這個答案應該是最佳答案!它比Django提出的解決方案更清潔!幹得好@Charlesthk – 2014-05-27 13:02:24

+2

超級有用。起初我並不明顯,但你可以用它來添加多個類:'{{form.subject | addclass:'myclass1 myclass2'}}' – smg 2016-12-17 00:45:36

2

真的沒有看到這個...

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

更精細的輸出

的as_p(),as_ul()和as_table()方法只是懶惰的開發人員快捷方式 - 他們沒有可以顯示的表單對象的唯一途徑。

class BoundField 用於顯示錶單實例的單個字段的HTML或訪問屬性。

STR()(關於Python 2 的unicode)此對象的方法顯示該字段的HTML。

檢索單個綁定列,使用字典查找語法窗體上使用字段名作爲鍵:

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

要檢索所有綁定列的對象,迭代形式:

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

根據this博客文章,您可以使用自定義模板過濾器將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"}} 
+1

這應該被接受爲這篇文章的真正答案:) – mvdb 2016-06-04 20:56:03

+0

最好的解決方案。 – 2017-03-02 19:14:50

0

在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

一種解決方案是使用JavaScript來添加所需的CSS類後的頁面已準備就緒。例如,定型的django形式輸出與自舉類(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> 

這避免了與業務邏輯混合造型細節的醜陋。

1

爲Django提供了一個非常簡單的安裝和優化工具,我可以用它來創建樣式,並且可以用於Bootstrap,Materialise,Foundation等每個前端框架。這就是所謂的小部件,調整文檔:

從Django的進口形式

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

相反:Widget Tweaks

  1. 你可以用Django的通用視圖
  2. 或者用自己的方式使用它使用默認值:

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

    您可以使用render_field屬性,讓你的造型像這樣實例的一個更類似HTML的方式編輯自己的路:

    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> 
    

    這個庫讓您有機會到將前端從後端分開很好