I intend to compare the value of an IntegerChoice inside Django Template :
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 %}
Yet, this does not get inside the true if case, and also does not like "()" at the end of "SomeModel.get_answer_display" with the following message :
Could not parse the remainder: '()' from 'SomeModel.get_answer_display()'
Inside view:
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
})
How can I make the filter work as expected?
In templates you do not call a function: in case something is a callable, Django will call the callable with no parameters, you thus render this with:
{% if somemodel.answer == SomeModel.Answer.YES %}
…
{% else %}
<h1>{{ somemodel.get_answer_display }}</<h1>
{% endif %}
You should also work with a model object, so somemodel
, not .SomeModel
In your view, you will need to pass both the somemodel
object and a reference to the SomeModel
class:
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}
)
Here somemodel
is also not a model object, it is a QuerySet
(a collection) of SomeModel
s. You thus should enumerate over these:
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}
)
and in the template enumerate over the collection:
{% for somemodel in somemodels %}
…
{% endfor %}
Note: You can limit views to a class-based view to authenticated users with the
LoginRequiredMixin
mixin [Django-doc].