私にはモデルがあります:
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を使用したいと思います。デフォルトのテンプレートは、選択の短いバージョン(「Fabulous eggs」ではなく「e」)を出力します。
{% for field in form %}
<tr>
<th>{{ field.label }}:</th>
<td>{{ field.data }}</td>
</tr>
{% endfor %}.
前述のように一般的なテンプレートが欲しいのですが、代わりに「Fabulous eggs」を印刷します。
[本当の質問はどこにあるのか疑っていたので、私たち全員のために太字にしました:)]
私はそれ自体がい方法で選択の冗長バージョンを取得する方法を知っています:
{{ form.meal.field.choices.1.1 }}
本当の痛みは、選択した選択肢を取得する必要があることです。頭に浮かぶ唯一の方法は、選択肢を繰り返して確認することです{% ifequals currentChoice.0 choiceField.data %}
、さらにいです。
簡単にできますか?または、テンプレートタグのプログラミングが必要ですか? Django=で既に利用可能になっていないはずですか?
Django=テンプレートでは、 " get_FOO_display()
"メソッドを使用できます。このメソッドは、フィールドの読み取り可能なエイリアスを返します。'FOO 'はフィールドの名前。
注:標準のFormPreview
テンプレートがそれを使用していない場合は、そのフォームに対して常に 独自のテンプレートを提供 できます。これには{{ form.get_meal_display }}
などが含まれます。
問題に対する最善の解決策は、ヘルパー関数を使用することです。選択肢が変数[〜#〜] choices [〜#〜]に保存され、選択された選択肢を保存するモデルフィールドが 'choices'である場合、直接使用できます。
{{ x.get_choices_display }}
テンプレートで。ここで、xはモデルインスタンスです。それが役に立てば幸い。
この回答が上記のリストと重複している場合はおaび申し上げますが、この回答はまだ提供されていないようです。これを私が解決した方法は次のとおりです。
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をテンプレートに渡し(注:not Scoop.values())、テンプレートには以下が含まれます:
{{ scoop.flavor_verbose }}
ノアの回答に基づいて、選択肢のないフィールドに影響されないバージョンを次に示します。
#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
そのような目的でフィルターを使用しても大丈夫かどうかはわかりません。誰かがより良い解決策を持っているなら、私はそれを見てうれしいです:)ノアありがとう!
Noah によってフィルターソリューションを拡張して、データとフィールドタイプをより普遍的に扱うことができます。
<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)
それを行う組み込みの方法はないと思います。ただし、フィルターがトリックを行う場合があります。
@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に1つの単純な関数を追加します。
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)
更新:確かではありませんが、そのソリューションは「Pythonic」と「Django-way」で十分かどうかですが、うまくいきます。 :)