【发布时间】:2018-08-12 00:15:45
【问题描述】:
我想要一个有 5 个选项的模型,但我不能强制它们并在模板中显示显示值。我使用 CharField(choice=..) 代替 docs 中的 ChoiceField 或 TypeChoiceField。我尝试了here 的解决方案,但它们对我不起作用(见下文)。
模型.py:
class Language(models.Model):
language = models.CharField(max_length=20,blank=False)
ILR_scale = (
(5, 'Native'),
(4, 'Full professional proficiency'),
(3, 'Professional working proficiency'),
(2, 'Limited professional proficiency'),
(1, 'Elementary professional proficiency')
)
level = models.CharField(help_text='Choice between 1 and 5', default=5, max_length=25, choices=ILR_scale)
def level_verbose(self):
return dict(Language.ILR_scale)[self.level]
class Meta:
ordering = ['level','id']
def __unicode__(self):
return ''.join([self.language, '-', self.level])
view.py
..
def index(request):
language = Language.objects.all()
..
我的模板.html
<div class="subheading strong-underlined mb-3 my-3">
Languages
</div>
{% regroup language|dictsortreversed:"level" by level as level_list %}
<ul>
{% for lan_list in level_list %}
<li>
{% for lan in lan_list.list %}
<strong>{{ lan.language }}</strong>: {{ lan.level_verbose }}{%if not forloop.last%},{%endif%}
{% endfor %}
</li>
{% endfor %}
</ul>
从外壳:
python3 manage.py shell
from resume.models import Language
l1=Language.objects.create(language='English',level=4)
l1.save()
l1.get_level_display() #This is good
Out[20]: 'Full professional proficiency'
一旦我从 shell 创建了 Language 实例,我就无法加载该站点。它在模板的第 0 行失败,异常类型:KeyError,异常值:'4',异常位置:level_verbose 中的 /models.py 第 175 行(这是 level_verbose 方法的返回行)。
另外,我预计 shell 会出现验证错误:
l1.level='asdasd'
l1.save() #Why can I save this instance with this level?
而且我还可以在使用 ChoiceField 时保存上面显示的内容,这意味着我不明白该字段的用途。
如何强制实例在选择中获取字段值,并在模板中显示显示值?
【问题讨论】:
-
它在字典中寻找字符串 '4' 而不是 4。试试 。 -
return dict(Language.ILR_scale)[int(self.leve)] -
您正在混淆字符串和整数。如果您想使用整数键,您可能应该使用
IntegerField而不是CharField。这将确保在保存之前将值正确转换为整数。 -
是的,解决了它。我认为 ChoiceField 是用于表单,而不是用于模型