【问题标题】:How to compare IntegerChoice values in Django Templates如何比较 Django 模板中的 IntegerChoice 值
【发布时间】:2021-08-25 17:10:40
【问题描述】:

我打算在 Django 模板中比较 IntegerChoice 的值:

class SomeModel(models.Model):
    class Answer(models.IntegerChoices):
        NO = 0, _('No')
        YES = 1, _('Yes')
    
        __empty__ = _('(Unknown)')
    answer = models.IntegerField(choices=Answer.choices)

SomeModel.objects.create(answer=0)
somemodel = SomeModel.objects.filter(answer=0)

Inside template :

{% if somemodel.answer == SomeModel.Answer.YES %}
    ...
{% else %}
    <h1>{{ somemodel.get_answer_display() }}</<h1>
{% endif %}

然而,这并没有进入真正的 if 情况,也不喜欢 "SomeModel.get_answer_display" 末尾的 "()" 以及以下消息:

Could not parse the remainder: '()' from 'SomeModel.get_answer_display()'

内景:

class BrowseView(View):
    @method_decorator(login_required(login_url='/login/'))
    def get(self, request):
        somemodel = SomeModel.objects.all()
        return render(self.request, 'browse/index.html',
                      {
                       'somemodel': somemodel
                      })

如何使过滤器按预期工作?

【问题讨论】:

  • 删除() 所以SomeModel.get_answer_display,Django 模板语言支持有限的语法,以便将业务逻辑与表示逻辑分开。模板引擎会自动调用不带任何参数的方法
  • somemodel 是 QuerySet 而不是 SomeModelinstance 因此 somemodel.get_answer_display 没有多大意义,除非有一个你没有在问题...

标签: django django-models django-templates django-filter


【解决方案1】:

在模板中你不调用函数:如果某些东西是可调用的,Django 将调用不带参数的可调用对象,因此你可以这样渲染:

{% if somemodel.answer == SomeModel.Answer.YES %}
    …
{% else %}
    <h1>{{ somemodel.get_answer_display }}</<h1>
{% endif %}

您还应该使用模型对象,所以somemodel,而不是SomeModel

在您看来,您需要同时传递somemodel 对象 和对SomeModel 的引用

from django.contrib.auth.mixins import LoginRequiredMixin

class BrowseView(LoginRequiredMixin, View):
    login_url = '/login/'
    
    def get(self, request):
        somemodel = SomeModel.objects.all()
        return render(
            self.request,
            'browse/index.html',
            {'somemodel': somemodel, 'SomeModel': SomeModel}
        )

这里somemodel不是模型对象,它是SomeModels 的QuerySet(一个集合)。因此,您应该列举这些:

from django.contrib.auth.mixins import LoginRequiredMixin

class BrowseView(LoginRequiredMixin, View):
    login_url = '/login/'

    def get(self, request):
        somemodels = SomeModel.objects.all()
        return render(
            self.request,
            'browse/index.html',
            {'somemodels': somemodels, 'SomeModel': SomeModel}
        )

并在模板中枚举集合:

{% for somemodel in somemodels %}
    …
{% endfor %}

注意:您可以将视图限制为基于类的视图,以向经过身份验证的用户提供 LoginRequiredMixin mixin [Django-doc].

【讨论】:

  • somemodel.get_answer_display 仍然给我数值,你认为我可能做错了吗?
  • @SuperEye:可以编辑问题并显示对应视图吗?
  • @WillemVanOnsem 模型实际上并不需要传递,我们可以简单地通过实例本身访问它somemodel.answer == somemodel.Answer.YES(之前使用过类似的东西)
  • @AbdulAzizBarkat,您的建议很有道理,并提供了一种通过对象使用枚举的便捷方式。如果您提供该答案作为答案,我可以将其标记为正确。
  • @SuperEye 已经有一个答案时无需发布多个答案(一个好的且有效的答案);)
猜你喜欢
  • 2022-12-29
  • 2011-04-17
  • 2019-01-19
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多