使用Django模板的这一部分。 regs是Reg对象的列表。 Reg.editable是一个BooleanField。 我想在列表中为每个元素渲染一个单选按钮。如果r.editable为False,则必须禁用单选按钮:
{% 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检查第一个单选按钮,但这有问题!如果第一个元素有editable == False怎么办?第一个单选按钮将被禁用并加载。如果用户提交“表单”,我将收到一个不期望的值。
我清楚这个问题吗?如何重写此模板以在选中FIRST ENABLED单选按钮时进行渲染?
由于
答案 0 :(得分: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 } )
在这种情况下,我们已经包装了QuerySet,它将为我们的模板提供有关渲染的更多细节。模板现在变得“愚蠢”。
{% 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 %}
答案 1 :(得分: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:你的问题没有清楚地解释你想要什么。我做了一些合理的假设。如果您想要的是其他内容,请更新问题。
答案 2 :(得分:1)
此问题的真实答案如下:
这种逻辑在模板中没有位置。您可以在将上下文传递给模板之前对其进行预处理,从而无需使用(故意)残缺的模板引擎逻辑来实现此目的。
在我看来,你所做的是错的。我的意思是,django有完美的形式api,为什么直接渲染输入呢?有些人可能会争辩说,django的形式api是不灵活的,但对于这个特定的需要,它无疑是足够的。
并重申 - 这种逻辑不属于表示层。所以不要把它放在那里,它会咬你。事实上它已经做到了。
答案 3 :(得分:0)
类似于T. Stone在视图中执行此逻辑的答案,您可以添加一个新的模板变量来指示第一个已检查的无线电:
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 %}
答案 4 :(得分:0)
与BecomeGuru类似但解决问题:
{% 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是否可编辑,然后检查它是否是第一个。 问候。