2009-11-27 30 views
37

我遍歷表單的字段和某些字段,我想要稍微不同的佈局,需要更改HTML。從模板中獲取Django表單部件的類型

要做到這一點準確,我只需要知道小部件類型。它的類名或類似的東西。在標準的Python中,這很簡單! field.field.widget.__class__.__name__

不幸的是,您不允許訪問模板中的下劃線變量。 太棒了!

可以測試field.field.widget.input_type但文/密碼<input ../>類型這隻作品。那我需要更多的解決方案。

對我來說,無論它看起來有多困難,最好在模板級別做到這一點。我已經將處理HTML字段的代碼外包給了包含在字段循環中的單獨模板。這意味着它在ModelForm s和標準Form s之間是一致的(如果我編寫了中介Form類,那麼這是不正確的)。

如果您能看到一種不需要我編輯20多種表格的通用方法,請讓我知道!

+0

相關錯誤報告或功能請求:https://code.djangoproject.com/ticket/13009 – Flimm

回答

4

由於Django的1.11的,你可以只使用widget.input_type。示例:

{% for field in form.visible_fields %} 
    <input type="{{ field.field.widget.input_type }}" 
      id="{{ field.id_for_label }}" 
      name="{{ field.html_name }}" 
      placeholder="{{ field.label }}" 
      maxlength="{{ field.field.max_length }}" /> 
{% endfor %} 
40

製作模板標籤可能有效嗎?像field.field.widget|widget_type

編輯奧利:好點!我只是寫了一個過濾器:

from django import template 
register = template.Library() 

@register.filter('klass') 
def klass(ob): 
    return ob.__class__.__name__ 

現在{{ object|klass }}呈現正確。現在我只需要弄清楚如何在模板的if語句中使用它。從奧利#2

編輯:我需要使用的,其結果在if statetement的模板,所以我只是轉移所有的邏輯到templatetag。魔法。感謝您向正確的方向傾斜。

+0

歡迎來到SO btw。 – Oli

+1

感謝您的解決方案。關於編輯#2 - 在Django 1.2中增強了if標籤,您可以在模板中直接進行這些小部件類型比較。我作爲一個單獨的答案發布了一個例子。 – zlovelady

+1

另一個不錯的過濾器添加(如果非Python人將處理您的模板)是這樣的,爲您最常用的情況: 'def is_checkboxes(form_field_obj): return(form_field_obj .__ class __.__ name__ ==「CheckboxSelectMultiple 「)...然後你可以做'{%if field | is_checkboxes%}'並且人們不會嚇壞了(...沒有返回) – hangtwenty

33

根據已接受的答案 - Django 1.2中增強的if tag允許您使用if tag比較中的過濾器。所以,你現在就可以做你的自定義HTML /邏輯在模板中像這樣:

<ul> 
{% for field in form.fields %} 
    <li> 
    {% if field.field.widget|klass == "Textarea" %} 
    <!-- do something special for Textarea --> 
    <h2>Text Areas are Special </h2> 
    {% else %}  
     {{ field.errors }} 
     {{ field.label_tag }} 
     {{ field }} 
    {% endif %} 

    </li> 
{% endfor %} 
</ul> 
+3

+1爲後續 – Oli

+0

* field.field.widget *的目的是什麼,而不是僅僅使用* field.widget *? – Wipqozn

+0

@Wipqozn在我的經驗'field.widget'往往不會產生任何 - 我不知道這一點,但也許它只是如果你手動設置它。 'field.field.widget'起作用。 – hangtwenty

16

在從奧利和rinti答案:我用這一個,我認爲這是一個有點簡單:

模板代碼:{{ field|fieldtype }}

過濾代碼:

from django import template 
register = template.Library() 

@register.filter('fieldtype') 
def fieldtype(field): 
    return field.field.widget.__class__.__name__