如何创建一个在复选框右侧显示复选框标签的Django表单? [英] How do I create a Django form that displays a checkbox label to the right of the checkbox?

查看:382
本文介绍了如何创建一个在复选框右侧显示复选框标签的Django表单?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我定义一个类似下面的Django表单类:

  def class MyForm(forms.Form):
check = forms.BooleanField(required = True,label =Check this)

类似下面的HTML:

 < form action =。 id =formmethod = POST> 
< p>< label for =check>检查:< / label> < input type =checkboxname =checkid =check/>< / p>
< p>< input type = submit value =Submit>< / p>
< / form>

我想复选框input元素在复选框后面有一个标签, 。有没有办法说服Django这样做?





感谢Jonas的答案 - 仍然,虽然它修复了我问的问题(复选框标签呈现在复选框的右侧),它引入了一个新的问题(所有窗口小部件标签都呈现在窗口小部件的右侧... )



我想避免重写_html_output(),因为它显然不是为它设计的。我想出的设计是在Field类中实现一个字段html输出方法,重写一个布尔字段,并在_html_output()中使用该方法。可悲的是,Django开发人员选择了不同的方式,我想尽可能在​​现有框架内工作。



CSS听起来像一个不错的方法,除了我不知道足够的CSS来拉这个,甚至决定我是否喜欢这种方法。此外,我喜欢仍然类似于最终输出的标记,至少在渲染顺序上。



此外,由于可以合理地为任何特定标记,在CSS这样做可能意味着必须多次为多个样式,这几乎使CSS是错误的答案。





看起来像我在回答我自己的问题。

解决方案

这里是我最后做的事。如果有任何人有更好的想法如何做到这一点。我写了一个自定义模板stringfilter来切换标签。现在,我的模板代码看起来像这样:

  {%load pretty_forms%} 
< form action = 。 method =POST>
{{form.as_p | pretty_checkbox}}
< p>< input type =submitvalue =Submit>< / p&
< / form>

与纯朴的Django模板的唯一区别是添加了{%load%}模板标签, pretty_checkbox 过滤器。



下面是 pretty_checkbox 的一个功能性但丑陋的实现:此代码没有任何错误处理,它假定Django生成的属性以非常具体的方式格式化,在代码中使用这样的东西是一个坏主意:

  from django import template 
from django.template.defaultfilters import stringfilter
import logging

register = template.Library()

@ register.filter(name ='pretty_checkbox')
@stringfilter
def pretty_checkbox(value):
#遍历HTML片段,提取< label>和< input>标签,
#切换输入类型为checkbox的对的顺序。
scratch = value
output =''
try:
while True:
ls = scratch.find('< label')
如果ls > -1:
le = scratch.find('< / label>')
ins = scratch.find('< input')
ine = scratch.find('/> ;',ins)
#检查我们是否处理一个复选框:
if scratch [ins:ine + 2] .find('type =checkbox'')> -1:
#切换变量
输出+ = scratch [:ls]
输出+ = scratch [ins:ine + 2]
输出+ = scratch [ls:le-1] scratch [le:le + 8]
else:
output + = scratch [:ine + 2]
scratch = scratch [ine + 2:]
else:
输出+ = scratch
break
except:
logging.error(pretty_checkbox捕获到异常)
返回输出
pre>

pretty_checkbox 扫描其字符串参数,找到< label>和< input>标签,并且如果< input>标签的类型是复选框。



优点:




  • 缺点:


    1. 过滤器代码需要针对标签和输入字段名称的激励值进行测试。

    2. 有可能是某些地方,它更好,更快。

    3. 比我计划在星期六做更多的工作。


    When I define a Django form class similar to this:

    def class MyForm(forms.Form):
        check = forms.BooleanField(required=True, label="Check this")
    

    It expands to HTML that looks like this:

    <form action="." id="form" method=POST>
    <p><label for="check">Check this:</label> <input type="checkbox" name="check" id="check" /></p>
    <p><input type=submit value="Submit"></p>
    </form>
    

    I would like the checkbox input element to have a label that follows the checkbox, not the other way around. Is there a way to convince Django to do that?

    [Edit]

    Thanks for the answer from Jonas - still, while it fixes the issue I asked about (checkbox labels are rendered to the right of the checkbox) it introduces a new problem (all widget labels are rendered to the right of their widgets...)

    I'd like to avoid overriding _html_output() since it's obviously not designed for it. The design I would come up with would be to implement a field html output method in the Field classes, override the one for the Boolean field and use that method in _html_output(). Sadly, the Django developers chose to go a different way, and I would like to work within the existing framework as much as possible.

    CSS sounds like a decent approach, except that I don't know enough CSS to pull this off or even to decide whether I like this approach or not. Besides, I prefer markup that still resembles the final output, at least in rendering order.

    Furthermore, since it can be reasonable to have more than one style sheet for any particular markup, doing this in CSS could mean having to do it multiple times for multiple styles, which pretty much makes CSS the wrong answer.

    [Edit]

    Seems like I'm answering my own question below. If anyone has a better idea how to do this, don't be shy.

    解决方案

    Here's what I ended up doing. I wrote a custom template stringfilter to switch the tags around. Now, my template code looks like this:

    {% load pretty_forms %}
    <form action="." method="POST">
    {{ form.as_p|pretty_checkbox }}
    <p><input type="submit" value="Submit"></p>
    </form>
    

    The only difference from a plain Django template is the addition of the {% load %} template tag and the pretty_checkbox filter.

    Here's a functional but ugly implementation of pretty_checkbox - this code doesn't have any error handling, it assumes that the Django generated attributes are formatted in a very specific way, and it would be a bad idea to use anything like this in your code:

    from django import template
    from django.template.defaultfilters import stringfilter
    import logging
    
    register=template.Library()
    
    @register.filter(name='pretty_checkbox')
    @stringfilter
    def pretty_checkbox(value):
        # Iterate over the HTML fragment, extract <label> and <input> tags, and
        # switch the order of the pairs where the input type is "checkbox".
        scratch = value
        output = ''
        try:
            while True:
                ls = scratch.find('<label')
                if ls > -1:
                    le = scratch.find('</label>')
                    ins = scratch.find('<input')
                    ine = scratch.find('/>', ins)
                    # Check whether we're dealing with a checkbox:
                    if scratch[ins:ine+2].find(' type="checkbox" ')>-1:
                        # Switch the tags
                        output += scratch[:ls]
                        output += scratch[ins:ine+2]
                        output += scratch[ls:le-1]+scratch[le:le+8]
                    else:
                        output += scratch[:ine+2]
                    scratch = scratch[ine+2:]
                else:
                    output += scratch
                    break
        except:
            logging.error("pretty_checkbox caught an exception")
        return output
    

    pretty_checkbox scans its string argument, finds pairs of <label> and <input> tags, and switches them around if the <input> tag's type is "checkbox". It also strips the last character of the label, which happens to be the ':' character.

    Advantages:

    1. No futzing with CSS.
    2. The markup ends up looking the way it's supposed to.
    3. I didn't hack Django internals.
    4. The template is nice, compact and idiomatic.

    Disadvantages:

    1. The filter code needs to be tested for exciting values of the labels and input field names.
    2. There's probably something somewhere out there that does it better and faster.
    3. More work than I planned on doing on a Saturday.

    这篇关于如何创建一个在复选框右侧显示复选框标签的Django表单?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆