繁体   English   中英

Django模板:在字段上强制选择并使用get_FOO_display()打印显示值

[英]Django template: force choices on field and print display value with get_FOO_display()

我想要一个具有5个选择的模型,但是我无法实施它们并在模板中显示显示值。 我正在使用CharField(choice = ..)而不是docs中的ChoiceField或TypeChoiceField。 我在这里尝试了解决方案但是它们对我不起作用(请参阅下文)。

model.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()
..

mytemplate.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'

我从外壳程序创建语言实例后,就无法加载该站点。 它在模板的第0行失败,其异常类型为:KeyError,异常值:'4',异常位置:在level_verbose的第175行(这是level_verbose方法的返回行)中的/models.py。

另外,我还期望shell出现验证错误:

l1.level='asdasd'
l1.save()     #Why can I save this instance with this level?

而且,在使用ChoiceField时,我还可以保存上面显示的内容,这意味着我不了解该字段的用途。

如何强制实例在选项中采用字段值,并在模板中显示显示值?

好吧,即使我从django开始,这也是常见的问题。 因此,首先让我们看一下django的功能,您可以像下面那样进行操作(注意:您选择的情况下的值将存储为整数,因此您应该使用models.IntegerField而不是models.CharField ):

正如您在文档中所看到的, FOO是模型的字段名称。 在您的情况下,它是level因此当您要在shell或视图中访问相应的选择值时,可以使用如下所述的模型实例调用方法:

`l1.get_level_display()`

但是当您想在模板文件中访问它时,您需要像下面这样写:

{{ l1.get_level_display }}
  • 现在,让我们看一下您的方法level_verbose()如果您再次看到模型是一个类,而level_verbose()是您创建的方法,则可以像使用self.ILR_scale直接访问self.level

在创建ILR_scale字典的过程中,主要要注意的是键值是整数值(ie 1, 2, 3, 4, 5)但是您已经使用CharField()存储了返回字符串值的电平值(ie '1', '2', '3', '4' or '5')并且在python字典中,键1和“ 1”都不同,一个是整数,另一个是字符串。 因此,您可以将模型字段更改为models.IntegerField()或访问诸如

dict(self.ILR_scal)[int(self.level)]

您也可以使用models.CharField但必须将字段选项choices设置为元组。

例如:

FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'
LEVELS = (
    (FRESHMAN, 'Freshman'),
    (SOPHOMORE, 'Sophomore'),
    (JUNIOR, 'Junior'),
    (SENIOR, 'Senior'),
)
level = models.CharField(
    max_length=2,
    choices=LEVELS,
    default=FRESHMAN,
)

然后,您可以在模板中使用get_FOO_display()例如: {{l1.get_level_display}}

文档中查看更多

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM