如何比较 Django 模板中的 IntegerChoice 值

Posted

技术标签:

【中文标题】如何比较 Django 模板中的 IntegerChoice 值【英文标题】:How to compare IntegerChoice values in Django Templates 【发布时间】: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 没有多大意义,除非有一个你没有在问题... 【参考方案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 已经有一个答案时无需发布多个答案(一个好的且有效的答案);)

以上是关于如何比较 Django 模板中的 IntegerChoice 值的主要内容,如果未能解决你的问题,请参考以下文章

如何比较 Django 模板中的两个查询集?

如何将上下文变量与 Django 模板中的 SQL ID 进行比较?

Django模板中的Django不区分大小写字符串比较

比较 Django 模板中的 url

带有缓存加载器的 Jinja2 与 django 模板 - 性能比较如何?

如何比较两个for循环的值并在django模板中使用if语句?