I use Django 1.8.4 with Python 3.4
I have a model for tournaments that defines a method which returns a string if a subscription is forbidden.
class Tournament(models.Model):
name = models.CharField(max_length=200, null=True, blank=True)
subscriptions = models.ManyToManyField('ap_users.Profile')
is_subscription_open = models.BooleanField(default=True)
# ...
def why_subscription_impossible(self, request):
if not request.user.profile.is_profile_complete():
return 'Your profile is not complete'
elif not self.is_subscription_open:
return 'Subscriptions are closed'
elif <another_condition>:
return 'Another error message'
return None
I want to display the list of tournaments, using a generic ListView, and I want to use the result of the method to modify the way it is displayed:
<table class="table">
<thead>
<td>Tournament</td>
<td>Subscription</td>
</thead>
{% for tournament in tournament_list %}
<tr>
<td>{{ tournament.name }}</td>
<td>
{% if tournament.why_subscription_impossible %}
{{ tournament.why_subscription_impossible }}
{% else %}
<a href="{% url 'ap_tournament:subscribe' tournament.id %}">Subscribe</a>
{% endif %}
</td>
</tr>
{% endfor %}
</table>
The view is a class based generic view inherited from generic.ListView
.
class IndexView(generic.ListView):
template_name = 'ap_tournament/index.html'
def get_queryset(self):
return Tournament.objects.all()
The shown solution doesn't work, because I need to pass the current request, to get information about logged user. So I tried to add the result of the method to a context in the view
class IndexView(generic.ListView):
template_name = 'ap_tournament/index.html'
def get_queryset(self):
return Tournament.objects.all()
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
additional_ctx_info = []
for tournament in self.get_queryset():
additional_ctx_info.append({
'reason_to_not_subscribe': tournament.why_subscription_impossible(self.request)
})
context['subscr_info'] = additional_ctx_info
return context
Obviously, this doesn't work too. I don't know how to access to the subscr_info[n]
with n the current index in the tournament_list. I know the forloop.counter0
to get the index, but I can't use it in the template (or I don't know how). I tried :
{{ subscr_info.forloop.counter0.reason_to_not_subscribe }}
{{ subscr_info.{{forloop.counter0}}.reason_to_not_subscribe }}
I also tried to annotate the QuerySet in get_queryset() view method and read about aggregate(), but I feel that works only with operations supported by the database (AVG, COUNT, MAX, etc.).
I also feels that using a filter or a template tag will not work in my case since I need to use the result of the method in a if
tag.
Is there a better solution or a completely diffferent method to achieve what I want ?