모델이 있습니다.
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 템플릿에서 “get_FOO_display()
“메서드를 사용하면 필드의 읽을 수있는 별칭을 반환합니다. 여기서 ‘FOO’는 필드 이름입니다.
참고 : 표준 FormPreview
템플릿에서 사용하지 않는 경우 언제든지 해당 양식에 대해 자신 만의 템플릿 을 제공 할 수 있습니다 {{ form.get_meal_display }}
.
답변
문제에 대한 가장 좋은 해결책은 도우미 기능을 사용하는 것입니다. 선택 사항이 변수 CHOICES에 저장되고 선택한 선택 사항을 저장하는 모델 필드가 ‘ 선택 사항 ‘인 경우 직접 사용할 수 있습니다.
{{ 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 }}
답변
노아의 대답을 바탕으로 선택하지 않은 분야에 면역성이있는 버전이 있습니다.
#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>
코드는 다음과 같습니다.
#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에 하나의 간단한 함수를 추가하십시오.
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”가 충분하지 않더라도 작동합니다. 🙂