Django模板:选项的详细版本

Django模板:选项的详细版本,django,django-templates,django-forms,Django,Django Templates,Django Forms,我有一个模型: from django.db import models CHOICES = ( ('s', 'Glorious spam'), ('e', 'Fabulous eggs'), ) class MealOrder(models.Model): meal = models.CharField(max_length=8, choices=CHOICES) 我有一张表格: from django.forms import ModelForm class

我有一个模型:

from django.db import models

CHOICES = (
    ('s', 'Glorious spam'),
    ('e', 'Fabulous eggs'),
)

class MealOrder(models.Model):
    meal = models.CharField(max_length=8, choices=CHOICES)
我有一张表格:

from django.forms import ModelForm

class MealOrderForm(ModelForm):
    class Meta:
        model = MealOrder
我想使用formtools.preview。默认模板打印选项的短版本('e'而不是'Fableus eggs'),因为它使用

{% for field in form %}
<tr>
<th>{{ field.label }}:</th>
<td>{{ field.data }}</td>
</tr>
{% endfor %}.
真正的痛苦是我需要得到所选的选项,而我脑海中浮现的唯一方法就是反复选择并检查
{%ifequals currentChoice.0 choiceField.data%}
,这甚至更难看


这容易做到吗?或者它需要一些模板标记编程?这在django不是已经有了吗?

我认为没有任何内置的方法可以做到这一点。不过,过滤器也可以做到这一点:

@register.filter(name='display')
def display_value(bf):
    """Returns the display value of a BoundField"""
    return dict(bf.field.choices).get(bf.data, '')
然后你可以做:

{% for field in form %}
    <tr>
        <th>{{ field.label }}:</th>
        <td>{{ field.data|display }}</td>
    </tr>
{% endfor %}
{%用于表单%]中的字段
{{field.label}}:
{{field.data | display}
{%endfor%}

在Django模板中,您可以使用“”方法,该方法将返回字段的可读别名,其中“FOO”是字段的名称


注意:如果标准的
FormPreview
模板没有使用它,那么您可以始终为该表单创建一个模板,该表单将包含类似
{{form.get_-mean_-display}

的内容,根据Noah的回复,这里有一个不受字段影响的版本,没有选择:

#annoyances/templatetags/data_verbose.py
from django import template

register = template.Library()

@register.filter
def data_verbose(boundField):
    """
    Returns field's data or it's verbose version 
    for a field with choices defined.

    Usage::

        {% load data_verbose %}
        {{form.some_field|data_verbose}}
    """
    data = boundField.data
    field = boundField.field
    return hasattr(field, 'choices') and dict(field.choices).get(data,'') or data

我不确定使用过滤器是否可以达到这种目的。如果有人有更好的解决办法,我很高兴看到:)谢谢你,诺亚

我们可以扩展过滤器解决方案,使其在处理数据和字段类型时更加通用:

<table>
{% for item in query %}
    <tr>
        {% for field in fields %}
            <td>{{item|human_readable:field}}</td>
        {% endfor %}
    </tr>
{% endfor %}
</table>

解决问题的最佳方法是使用辅助函数。 如果选项存储在变量choices中,并且存储所选选项的模型字段为“choices”,则可以直接使用

 {{ x.get_choices_display }}
在模板中。这里,x是模型实例。
希望有帮助。

添加到您的模型中。py一个简单的功能:

def get_display(key, list):
    d = dict(list)
    if key in d:
        return d[key]
    return None
现在,您可以获得选择字段的详细值,如下所示:

class MealOrder(models.Model):
    meal = models.CharField(max_length=8, choices=CHOICES)

    def meal_verbose(self):
        return get_display(self.meal, CHOICES)    

Upd:我不确定,这个解决方案“pythonic”和“django-way”是否足够,但它是有效的

如果这个答案与上面列出的任何答案都是多余的,我深表歉意,但这个答案似乎还没有给出,而且看起来相当干净。下面是我如何解决这个问题的:

from django.db import models

class Scoop(models.Model):
    FLAVOR_CHOICES = [
        ('c', 'Chocolate'),
        ('v', 'Vanilla'),
    ]

    flavor = models.CharField(choices=FLAVOR_CHOICES)

    def flavor_verbose(self):
        return dict(Scoop.FLAVOR_CHOCIES)[self.flavor]
我的视图将一个独家新闻传递给模板(注意:不是独家新闻.values()),模板包含:

{{ scoop.flavor_verbose }}

您有Model.get\u FOO\u display(),其中FOO是具有选项的字段的名称

在模板中执行以下操作:

{{ scoop.get_flavor_display }}

是的,我知道。不过,它并不是通用的(通用的),除非你知道一种在模板中迭代模型对象的所有get_FOO_显示方法的方法:)我有点太懒了,不适合编写非通用的模板;)此外,文档称这是一个模型实例的方法。因此,它必须是绑定到现有对象的模型表单,而现有对象不是这种情况,也不是通用的。请注意,这种用法不仅限于视图,get\u FOO\u display()是模型对象本身的一个方法,因此您也可以在模型代码中使用它!例如,在uu unicode uuu()中,用+1来表示您的路径非常方便。。。英雄联盟我使用get_FOO_display(),这在表单docs的底部提到。在选项上使用hasattr是个好主意!似乎很普遍:)我不能确定,因为从那时起我就没有做过太多Python或Django。不过,很遗憾,它仍然需要一个第三方(不包括在Django中)过滤器(否则你会告诉我们,Ivan,不是吗?;)…@ArturGajowy是的,到今天为止,Django中还没有这样的默认功能。我已经提出了,太好了!工作起来很有魅力!自定义模板过滤器ROX!谢谢!:-)为什么在一个有用的答案已经存在两年后,你会这样回答?谁会投赞成票?这与仅仅两年后的@roberto的答案相同……@Mark0978之所以对这个答案进行投票,是因为(对我来说)遵循“得票最多”的答案更为清晰。YMMV。
{{ scoop.flavor_verbose }}
{{ scoop.get_flavor_display }}