Django模板:select的详细版本

我有一个模型:

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。 默认模板打印select的短版本('e',而不是'神话般的蛋'),因为它使用

 {% for field in form %} <tr> <th>{{ field.label }}:</th> <td>{{ field.data }}</td> </tr> {% endfor %}. 

我想要一个像上面提到的一般的模板,而是打印“神话般的蛋”。

[因为我怀疑真正的问题在哪里,我为所有人加上了粗体]

我知道如何以自己丑陋的方式获得select的详细版本:

 {{ form.meal.field.choices.1.1 }} 

真正的痛苦是我需要得到select的select,而我脑海中唯一的方法是迭代select并检查{% ifequals currentChoice.0 choiceField.data %} ,这更加丑陋。

它可以轻松完成吗? 或者它需要一些模板标签编程? 不应该在django中可用吗?

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

注意:如果标准的FormPreview模板没有使用它,那么你总是可以为这个表单提供你自己的模板 ,它将包含类似{{ form.get_meal_display }}东西。

您的问题的最佳解决scheme是使用帮助器function。 如果选项存储在variablesCHOICES中,并且存储所选选项的模型字段是“ select ”,则可以直接使用

  {{ x.get_choices_display }} 

在你的模板。 这里,x是模型实例。 希望能帮助到你。

我的道歉,如果这个答案是多余的任何上面列出,但似乎这一个还没有提供,而且看起来相当干净。 以下是我解决这个问题的方法:

 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] 

我的看法传递一个勺子到模板(注意: 不是 Scoop.values()),模板包含:

 {{ scoop.flavor_verbose }} 

根据诺亚的回答,这里有一个版本可以不受任何select的影响:

 #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 

我不确定使用filter是否合适。 如果有人有更好的解决scheme,我会很高兴看到它:)谢谢诺亚!

我们可以通过Noah扩展滤波器解决scheme,在处理数据和字段types方面更具普遍性:

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

代码如下:

 #app_name/templatetags/custom_tags.py def human_readable(value, arg): if hasattr(value, 'get_' + str(arg) + '_display'): return getattr(value, 'get_%s_display' % arg)() elif hasattr(value, str(arg)): if callable(getattr(value, str(arg))): return getattr(value, arg)() else: return getattr(value, arg) else: try: return value[arg] except KeyError: return settings.TEMPLATE_STRING_IF_INVALID register.filter('human_readable', human_readable) 

我不认为有任何内置的方式来做到这一点。 但是一个filter可能会诀窍:

 @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 %} 

添加到您的models.py一个简单的function:

 def get_display(key, list): d = dict(list) if key in d: return d[key] return None 

现在,你可以得到像这样的select字段的详细值:

 class MealOrder(models.Model): meal = models.CharField(max_length=8, choices=CHOICES) def meal_verbose(self): return get_display(self.meal, CHOICES) 

更新:我不知道,解决scheme“pythonic”和“django-way”是否足够,但它的工作原理。 🙂

随着模板标签的使用。

和Arthur Gawjowj几乎一样,但是这个select只能使用整数值而不是string。

 # project/templatetags/project_tags.py from django.template.base import Library register = Library() @register.filter(name='pretty_form_value') def pretty_form_value(field): """ Returns field's data or it's verbose version for a field with choices defined. Usage:: {% load project_tags %} {{form.some_field|pretty_form_value}} """ if hasattr(field.field, 'choices'): try: return dict(field.field.choices)[int(field.data)] except ValueError: pass return field.data