2009-11-22 120 views
0

修改Django模板的這部分。 regs是Reg對象的列表。 Reg.editable是一個BooleanField。 我想呈現列表中每個元素的單選按鈕。如果r.editable是假,單選按鈕必須禁用:Django模板中的邏輯問題

{% for r in regs %} 
<input type="radio" value="{{ forloop.counter }}" 
{% if forloop.first %}checked="checked"{% endif %} 
{% if not r.editable %}disabled="disabled"{% endif %}/> 
{% endfor %} 

正如你所看到的,我使用forloop.first檢查的第一個單選按鈕,但是這有一個問題!如果第一個元素具有可編輯== False,怎麼辦?第一個單選按鈕將被禁用並被選中。如果用戶提交「表單」,我會收到一個不值得期待的值。

我明白這個問題嗎?我怎樣才能重寫這個模板來渲染選中的FIRST ENABLED單選按鈕?

感謝

+0

順便說一句,我沒有使用洞Django,只是模板引擎,所以我不能將這個邏輯移動到視圖:) – 2009-11-22 17:15:18

回答

1

真正這個問題的答案如下:

這種邏輯在模板中沒有位置。您可以在將上下文傳遞給模板之前對其進行預處理,從而明確需要使用(有意)殘缺的模板引擎邏輯來執行此操作。

在我看來,你在做什麼是錯的。我的意思是,Django具有完美的形式API,爲什麼直接輸入輸入呢?有些人可能會爭辯說,Django的形式API是不靈活的,但對於這種特定的需求,它無疑是足夠的。

並重申 - 這種邏輯不屬於表示層。所以不要把它放在那裏,它會咬你。事實上它已經做到了。

1

只是調整if小號

{% for r in regs %} 
    {% if forloop.first %} 
     <input type="radio" value="{{ forloop.counter }}" checked="checked"/> 
    {% else %} 
     {% if not r.editable %} 
      <input type="radio" value="{{ forloop.counter }}" disabled="disabled"/> 
     {% endif %} 
    {% endif %} 
{% endfor %} 

PS:你的問題沒有解釋清楚你想要的東西。我做了一些合理的的假設。更新問題,如果你想要的是別的東西。

+0

這解決了第一個無線電的問題(檢查和禁用),但如果第一臺收音機應該(禁用並且未被檢查)怎麼辦? – 2009-11-22 16:23:50

2

Djangos模板語言在模板中並沒有給你很多邏輯(如果你想改變它,我已經聽到了有關Jinja2的積極信息)。還有"Smart" {% if %}標籤,它增加了更多的功能,並且順便提出將其包含在Django 1.2中。

至於解決這個問題,我很可能將邏輯轉移到視圖。 (免責聲明:沒有測試此代碼段的時間,但它應該提供的總體思路)

def my_view(request, *args, **kwargs): 

    # QuerySet is fetched however it's done... 
    regs = Regs.objects.all() 

    # Wrap regs in display information  
    checked = False 
    radio_buttons = [] 

    for r in regs: 
     if r.editable: 
      if not checked: 
       radio_buttons.append({ 'checked':True, 'enabled':True, 'object':r }) 
       # Set to true once 
       checked = True 
      else: 
       radio_buttons.append({ 'checked':False, 'enabled':True, 'object':r }) 
     else: 
      radio_buttons.append({ 'checked':False, 'enabled':False, 'object':r })   

    # Then pass in radio_buttons for the value of regs down here 
    render_to_whatever(..., { 'regs':radio_buttons }) 

在這種情況下,我們已經包裹查詢集,這將給我們的模板有關呈現一些細節。模板現在變成了「啞巴」。

{% for r in regs %} 
    <input type="radio" value="{{ forloop.counter }}" 
    {% if r.checked %}checked="checked"{% endif %} 
    {% if not r.enabled %}disabled="disabled"{% endif %}/> 
    {% comment %} To access the original object use: {{ r.object }} {% endcomment %} 
{% endfor %} 
0

與T.相似。在視圖中做這個邏輯斯通的回答,你可以只添加所指示的第一檢查無線電新模板變量:

def my_view(request, *args, **kwargs): 
    regs = Regs.objects.all() 
    checked_index = None 
    for i, reg in enumerate(regs): 
    if reg.enabled: 
     checked_index = i 
     break 
    # pass checked_index into the template... 

模板:

{% for r in regs %} 
    {% ifequal forloop.counter0 checked_index %} 
    <input type="radio" value="{{ forloop.counter }}" checked="checked"/> 
    {% else %} 
    <input type="radio" value="{{ forloop.counter }}" {% if not r.editable %}disabled="disabled"{% endif %}/> 
    {% endif %} 
{% endfor %} 
0

類似becomingGuru但解決你的問題:

{% for r in regs %} 
    {% if not r.editable %} 
     <input type="radio" value="{{ forloop.counter }}" disabled="disabled"/>  
    {% else %} 
     {% if forloop.first %} 
      <input type="radio" value="{{ forloop.counter }}" checked="checked"/> 
     {% endif %} 
    {% endif %} 
{% endfor %} 

它首先檢查r是否可編輯,然後檢查它是否是第一個。 此致敬禮。